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

How-To Tutorials

7019 Articles
article-image-navigating-online-drupal-community
Packt
16 Oct 2009
9 min read
Save for later

Navigating the Online Drupal Community

Packt
16 Oct 2009
9 min read
Recipe 87: Creating an issue Page Bookmark IngredientsWeb Browser The issue queue is the central place of progress for Drupal modules. It serves as a place to find answers, patches, new ideas, and work on common concerns. Issues are referenced by number. On occasion, a web page will contain an issue queue number in text form rather than a full link to the issue. This recipe, once set up, simply saves the trouble of having to type drupal.org/node/ into the browser address bar. Just select the number and the bookmark will take you there. In Firefox add a new Bookmark onto the toolbar. Select Bookmarks | Organize Bookmarks | Bookmarks Toolbar | Organize | New Bookmark Set the Name to Drupal Issue and set the Location to the following: javascript:inum=escape(getSelection());location.href='http://www.drupal.org/node/'+inum. Visit a web page that contains an issue number and select the issue number text. For instance, try http://cvs.drupal.org/viewvc.py/drupal/contributions/modules/views/modules/views_taxonomy.inc. (Be sure to exclude the surrounding space and pound sign when selecting the number.) Click the Drupal Issue button in the bookmark toolbar. Recipe notes This bookmark approach may be replicated to visit a URL containing any selectable text. For instance, below is a variation to display all of your delicious bookmarks tagged with the selected text. (Delicious.com—also found at http://del.icio.us, is a wonderful online bookmark service.) Replace <ACCOUNTNAME> with your delicious.com account. Name: DeliciousLocation: javascript_tag=escape(getSelection());location.href='http://delicious.com/<ACCOUNTNAME>/'+tag Recipe 88: Searching the Views issue queue IngredientsWeb Browser In this recipe we look closely at how to search the Views issue queue. The lessons apply to all other Drupal projects as well. It is always a good idea to search the issue queue for related content before posting. Log on to drupal.org (if you are not already a member of the Drupal site, become a member). Basic Search Visit http://drupal.org/project/issues/views. At this main issue queue page you may search for text or filter by Status, Priority, Category, Version, or Component. These options are discussed in further detail below. You may also sort the table of issues by clicking on the table header. By default, the table is sorted by date. Advanced Search Go to the Views issue queue Advanced Search page. Visit the URL directly, at http://drupal.org/project/issues/search/views. From the project page (drupal.org/project/views), find the Issues block on the left, and click on the Advanced Search link. From the issue queue (drupal.org/project/issues/views), the Advanced Search Link appears under the title. There are a variety of routes to get there: Get to know the search options. Although there are ten form elements to choose, most users will routinely use just a few, leaving the other options blank. Search For (Routinely used): Enter search text. Use quotation marks to create a phrase. Assigned: This field is generally used by issue maintainers. Submitted by: This is most often used to find your own issues, though it could be used to see what other Drupal users are posting as well. Participant: This is also used to find your own posts. Note that Submitted by finds only the initial post by a user in the issue queue. Participant additionally includes responses to initial posts. Status: Leave blank to get all statuses. You may also select multiple options. For instance, you could select all issues designated as needs work, needs review, and reviewed & tested by the community. Scroll down the list and note Status filters such as closed issues, duplicates, issues that the maintainer won't fix, and features noted as by design. These are the statuses that are excluded if you select -Open Issues-. Priority: Leave blank to get all priorities. Category: Leave blank to get all categories. Version (Routinely used): A relative new option, 5.x issues saves you the trouble of having to Shift+click on each Drupal 5 release name. Component: The views module issue queue offers more component options than most modules. As a result, users may not always be familiar with properly assigning a component when they create an issue. A search of exposed filters components, for instance, may not find as many results as a text search of "exposed filters." Component can occasionally be a helpful selection, but is most often left blank. Issue Tags: These may be a challenge to search since few people add tag issues. This may become a more popular option in the future. Recipe notes Search ideas: Find all your posts by filling in your drupal.org user name under participant. Find patches by selecting all of the four patch statuses. Find all documentation issues connected to Views for Drupal 5.x. Go to another issue queue http://drupal.org/project/issues/search/<MODULENAME> and search for the word Views. From the module issue pages http://drupal.org/project/issues/<MODULENAME> you may also review module Statistics, and Subscribe to issues. Subscribe to your Own Issues (the default), None, or All Issues. I don't recommend the latter for the Views module as you will be setting yourself up for a deluge of email. Search across all projects at http://drupal.org/search/issues. Recipe 89: Posting an issue Posting a New issue If you are new to posting Drupal issues, consider just reading the issue queue for at least several days before posting. This will help you to get a sense of the culture of issue queue interaction. If you don't already have an account on drupal.org get one. Look for the User login block on the home page, and click on Create new account. Complete the steps to login. Search the issue queue before you post! (Recipe 88). If your topic already has an associated active issue, reply rather than posting a new issue.Also, before posting to the issue queue in a panic read the Drupal Troubleshooting FAQ http://drupal.org/Troubleshooting-FAQ. For instance, standard fare is to increase memory in the face of the White Screen of Death (WSOD) or to disable buggy modules by setting the status = 0 in the system table. Be sure to know which version of the module you're using. Is it the dev (development) version? Is it the latest recommended release? The version number can generally be found at http://YOURSITE.com/admin/build/modules. To start a new issue, go to http://drupal.org/project/issues/<MODULENAME> and click on Create a new issue. This directs the browser to: http://drupal.org/node/add/project-issue/<MODULENAME>. For the Views module, the link at http://drupal.org/node/add/project-issue/views offers guidance (in bold!) for posting. Read it! Much of it applies to Views 2 but it contains useful information for Views 1 users as well. Required fields for a new issue include Version, Component, Category, Title, and Description. Be thoughtful with these details. For instance, do not title your issue HELP??!! A much more useful description would be something like Missing taxonomy terms in filters. Priority should generally be left as normal. Critical is reserved for occasions then the module simply does not work. Responding to an existing issue You may also respond to an existing issue by selecting the Add New Comment link or one of the Reply links on an individual issue page. Another option is just to scroll down to the bottom of the issue page, and begin entering a response. Unlike some forum tools, in which replies are indented, all new comments are given a new comment number, and added to the bottom of the comments. When responding to an issue you may take a variety of actions: Change the Issue Title. In general, don't change this unless you have a very good reason (for instance, if the original title is misleading, or spelled wrong). Some people are used to forums where a response can have a different name as the original post. In the issue queue, changing the name when responding to an issue actually changes the name of the issue. This is generally best left untouched. Change the Project. A question that someone asks in the Views issue queue may be more appropriately managed in the issue queue for a different module. This is a rare change generally left to the maintainer of one of the two modules who will know in which issue queue a discussion belongs. Change the Version number, Component, Category, or Priority. These changes are rare (correcting the version number is probably the most common). When changes are made, they are noted in the post as shown below: Change Assign. Do not assign someone other than yourself to an issue. Assign yourself if you are sure that you will soon fix the issue. It is quite common to leave this as Unassigned. Change the Status. For instance: Mark an issue as a duplicate (always provide a pointer to the issue it duplicates). Note that a patch is reviewed and tested by the community. Post a question, patch, answer, or idea related to the issue in the Comment section. Open the Input format fieldset below the comment field to see what markup is available. Note the <code> tag, for instance (and remember to close it with a </code> tag). Attach a file. Recipe notes Remember that respondents and maintainers are volunteers. They are generally very busy people who want to help, but they do not have time to do free consulting. See the following pages for spirited discussions about issue queue etiquette: http://acko.net/blog/whats-wrong-with-drupal http://paul.leafish.co.uk/articles/drupal/on_subscribing_to_module_portingupdating_issues One discussion theme is the merit of simply sending the word subscribe to the issue queue. People sometimes do this so that they can track an issue—receiving an email alert each time something new is posted. On drupal.org it is possible to subscribe to a node only if you leave a comment, but most people prefer comments with substance. You may create functionality similar to the Drupal issue queue on your own site by installing the project, project_issue, and comment_upload modules.
Read more
  • 0
  • 0
  • 3868

article-image-storing-planning-data-ibm-cognos-d-cube-part-1
Packt
16 Oct 2009
10 min read
Save for later

Storing Planning Data in IBM Cognos: D-Cube (Part 1)

Packt
16 Oct 2009
10 min read
Overview of the D-Cube In Analyst, data is stored in a D-Cube. The D-Cube is a multi-dimensional data structure similar to an OLAP or Excel pivot table. Each of the dimensions contains a list of related data. For example, in a four dimensional cube, the first dimension may contain the items in  P&L statement, the second may list the departments, the third show the timescale, and the fourth may show the version (Budget or Actual). In this example, you have the  P&L statement by month, by department, and by version. The D-Cube must have at least two dimensions. If more than two dimensions exist, the other dimensions appear as pages. The following screenshot depicts a four dimensional D-Cube. The first two dimensions form the rows and columns. The third and fourth dimensions are displayed as pages, in the upper-left corner of the D-Cube. You can switch to different pages in the cube by clicking the page drop-down list and selecting another page. Creating a D-Cube Creating a D-Cube takes a few simple steps but it requires a great deal of forethought. Before creating the D-Cube, you must think through the dimensions that will form the cube. You must know what data will populate the D-Cube. You must know what category of D-Lists your selection falls under so that you can prioritize the calculations appropriately. You must know what function the D-Cube performs. Is it an input cube, a calculation cube, a summary or reporting cube, or a staging cube? You must also know in which library the D-Cube will be stored, and whether the D-Cube will be shared or will be exclusive to a model. Finally, you must consider size and performance, especially if you plan to deploy the D-Cube in Contributor. To create a D-Cube: Click on File | New | D-Cube. In the Create new D-Cube box, select the D-List that makes up the D-Cube. Drop the D-List onto the lower pane. Order the D-List. Click on OK. Enter the D-Cube name, and then click on OK. By default, the D-Cube opens with the longest D-List as the rows and the timescale as the columns. You can transpose the cube or swap the dimensions by dragging and dropping them. When you close and reopen the D-Cube, it will revert to the default view. Order of dimensions It is important to have the proper order of dimensions in the D-Cube. The order of dimensions is important because it determines which calculation takes precedence when calculations from two separate D-Lists intersect. The order also determines the priority of formats when the cell has opposing formats. As a rule, the dimensions must follow this order: Calculation: Calculation D-Lists contain mathematical operations over and above simple addition. Any use of operators, such as multiplication, subtraction, division, or the use of a BiF, make the D-List a calculation D-List. Aggregation: Aggregation D-Lists usually contain a hierarchy of items, such as an organizational hierarchy, a list of products, customers, or cost centers, or a list of items with a simple subtotal. Non-Calculating: Non-Calculating D-Lists contain no calculations. Timescale: Timescale D-Lists contains items that span a period of time, such as months, weeks, or days. Versions: Version D-Lists contain iterations of the data, such as Actual, Budget, Forecast, and Revised Budget. It is critical to set the proper order of dimensions before building the Contributor application. If you reorder the dimensions after the application is created, all of the data in the D-Cube will be deleted. In addition, reordering dimensions changes the structure of the import tables and, therefore, the way that you import data into Contributor. Size considerations The size of the D-Cube is measured by the number of cells in it. The number of cells you can have in a D-Cube is limited only by your computer's memory. When you build a D-Cube, you should keep in mind the amount of memory available on the computer on which the model will be used. You will not be able to open a large cube if your PC does not have enough memory to handle the data. If the model is deployed in Contributor, size is an even more important consideration. Even with a powerful computer, you will experience performance lag because a large model must pass through the organization's network. In a wide area network, the problem associated with a large model becomes more apparent. To determine the number of cells, find the product of the number of items in all of the D-lists in the D-Cube. For instance, if a D-Cube has five D-Lists, which have the following number of items: 8, 1, 10, 5, and 12, the number of cells in the D-Cube will be 4,800. This is 8*1*10*5*12. You can find the number of cells in the dimension selection box, as illustrated in the following screenshot: The number of items in a dimension has an inverse impact on the magnitude of size increases for additions to the cube. The fewer the items, the bigger the impact that an addition will have to the size of the cube. In the example of the cube above, if you add one item to a dimension that has only one item, you will double the size of the cube. However, if you add one item to a dimension that has 10 items, you will increase the size of the cube by only ten percent. One clue that your D-Cube may have a problem with size is the number of dimensions. While there is no limitation on the number of dimensions that a cube can have, having too many of them can become a problem. With a D-Cube that has too many dimensions, any additional item in one of the D-Lists increases the size in an order of magnitude depending on the number of items in the D-List. If possible, keep the number of dimensions to not more than five. If you need to have a D-Cube that provides views of data beyond five dimensions, consider splitting the D-Cube. You are more likely to require less memory if you have several smaller cubes than with one super cube. With Analyst, you can open a D-Cube that has several million cells on a PC that has 512MB of RAM. However, if you plan to deploy the model in Contributor, the threshold for the number of cells is much lower. An acceptable benchmark is roughly 500,000 cells per e.List. This benchmark is subject to many other factors, such as network latency, client PC memory, and CPU, all of which can contribute to model performance. Working with the D-Cube When working with the D-Cube, you have several functionalities that help you to hone in on the information that you want. By default, the D-Cube opens in full view, but you can open only a slice of the cube and save the slice for later viewing. Opening a full view of the D-Cube The most straightforward way to view the D-Cube is to open all dimensions. To open a full D-Cube: Click on File | Open | D-Cube. Select the D-Cube. Click on OK. Select the Full option. Click on OK. Opening a selection of the D-Cube A selection is a subset of a D-Cube. You can only open the specific items of the dimensions that you want to view. Because the data in a selection is fewer than the full view, less memory is required and the D-Cube opens and recalculates faster. To open a selection of the D-Cube: Click on File | Open | D-Cube. Select the D-Cube. Click on OK. Select the Edit Selection option. This option opens the dimension selection box, where you can select the items that you want to view in the D-Cube slice. As shown in the following illustration, the item selection box lets you select the items from a dimension that you want to include in your view. In the item selection box, each tab represents a D-List. To select the items, move the items from the Items available pane (on the left) to the Items included pane (on the right). Click on OK. Viewing different slices of the D-Cube You can view the D-Cube in a variety of ways. You can open a selection of the D-Cube, or several selections at the same time. If you have a selection open, you can change it to another selection. The ability to switch views makes it easier to work with the D-Cube. For instance, suppose you have a D-Cube that has two versions: Budget and Actual. If you want to enter only budget data, you may want to open only the Budget dimension and keep the Actual dimension closed. You can have multiple selections of the D-Cube open at the same time in the same way that you open the D-Cube. This allows you to arrange the selections next to each other on the same screen. To modify the views of the D-Cube: With the D-Cube open, click on D-CubeSelections: New Slice: This option allows you to create a new view of the same D-Cube, with the same selection. Reselect: Modify the current selection. Selecting this option allows you to add or remove dimensions in the current view. Save: Save the current selection as a saved selection. This option allows you to save the current view so that you can open it again later. If you select Reselect, move the items that you want to add to or remove from the current view from the Items included to the Items available pane, or vice versa, respectively. Click on OK. Saving a selection You can select a view of a D-Cube and then save this selection so that you do not have to reselect the same view the next time that you open the cube. When you save a selection, you create a "saved selection"—an object that is derived from the cube. To save a selection: Click File | Open | D-Cube. Select the D-Cube. Under Mode, select Edit Selection. Select the D-List items that you want to view in the D-Cube, and move them from the Items available pane to the Items included pane. If you do not select anything in the Items available pane, then all of the items will be included in the selection, including any future additions to the D-List. Under the Save Selections option on the lower-right corner of the dialog box, click on the Save button. Enter the name of the saved selection. Click on OK. If you have a saved selection, you can load it into the item selection box. The dimension item selection box is used in many functions, including export, D-List imports, and D-Cube allocations (to be discussed later). Opening the saved selection Once saved, the selection becomes a separate object that can be copied and shared. However, because it is a subset of the cube, you have to go through the cube to access the saved selection. To open the saved selection: Click on File | Open | D-Cube. Select the D-Cube. Under Mode, select Saved Selection. Select the Saved Selection. Click on OK    
Read more
  • 0
  • 0
  • 2375

article-image-windows-development-using-visual-studio-2008
Packt
16 Oct 2009
11 min read
Save for later

Windows Development Using Visual Studio 2008

Packt
16 Oct 2009
11 min read
Visual Studio Visual Studio is an environment for developing applications in Windows. It has a number of tools, such as an editor, compilers, linkers, a debugger, and a project manager. It also has several Wizards—tools designed for rapid development. The Wizard you will first encounter is the Application Wizard. It generates code for an Application Framework. The idea is that we use the Application Wizard to design a skeleton application that is later completed with more application-specific code. There is no real magic about wizards, all they do is generate the skeleton code. We could write the code ourselves, but it is a rather tedious job. Moreover, an application can be run in either debug or release mode. In debug mode, additional information is added in order to allow debugging; in release mode, all such information is omitted in order to make the execution as fast as possible. The code of this article is developed with Visual Studio 2008. The Windows 32 bits Application Programming Interface (Win32 API) is a huge C function library. It contains a couple of thousand functions for managing the Windows system. With the help of Win32 API it is possible to totally control the Windows operating system. However, as the library is written in C, it could be a rather tedious job to develop a large application, even though it is quite possible. That is the main reason for the existence of the Microsoft Foundation Classes (MFC). It is a large C++ class library containing many classes encapsulating the functionality of Win32 API. It does also hold some generic classes to handle lists, maps, and arrays. MFC combines the power of Win32 API with the advantages of C++. However, on some occasions MFC is not enough. When that happens, we can simply call an appropriable Win32 API function, even though the application is written in C++ and uses MFC. Most of the classes of MFC belong to a class hierarchy with CObject at the top. On some occasions, we have to let our classes inherit CObject in order to achieve some special functionality. The baseclass Figure in the Draw and Tetris applications inherits CObject in order to read or write objects of unknown classes. The methods UpdateAllViews and OnUpdate communicate by sending pointers to CObject objects. The Windows main class is CWnd. In this environment, there is no function main. Actually, there is a main, but it is embedded in the framework. We do not write our own main function, and there is not one generated by the Application Wizard. Instead, there is the object theApp, which is an instance of the application class. The application is launched by its constructor. When the first version of MFC was released, there was no standard logical type in C++. Therefore, the type BOOL with the values TRUE and FALSE was introduced. After that, the type bool was introduced to C++. We must use BOOL when dealing with MFC method calls, and we could use bool otherwise. However, in order to keep things simple, let us use BOOL everywhere. In the same way, there is a MFC class CString that we must use when calling MFC methods. We could use the C++ built-in class string otherwise. However, let us use CString everywhere. The two classes are more or less equivalent. There are two types for storing a character, char and wchar_t. In earlier version of Windows, you were supposed to use char for handling text, and in more modern versions you use wchar_t. In order to make our application independent of which version it is run on, there are two macros TCHAR and TEXT. TCHAR is the character type that replaces char and wchar_t. TEXT is intended to encapsulate character and string constants. TCHAR *pBuffer;stScore.Format(TEXT("Score: %d."), iScore); There is also the MFC type BYTE which holds a value of the size of one byte, and UINT which is shorthand for unsigned integer. Finally, all generated framework classes have a capital C at the beginning of the name. The classes we write ourselves do not. The Document/View model The applications in this article are based on the Document/View model. Its main idea is to have two classes with different responsibilities. Let us say we name the application Demo, the Application Wizard will name the document class CDemoDoc and the view class will be named CDemoView. The view class has two responsibilities: to accept input from the user by the keyboard or the mouse, and to repaint the client area (partly or completely) at the request of the document class or the system. The document's responsibility is mainly to manage and modify the application data. The model comes in two forms: Single Document Interface (SDI) and Multiple Document Interface (MDI). When the application starts, a document object and a view object are created, and connected to each other. In the SDI, it will continue that way. In the MDI form, the users can then add or remove as many views they want to. There is always exactly one document object, but there may be one or more view objects, or no one at all. The objects are connected to each other by pointers. The document object has a list of pointers to the associated view objects. Each view object has a fieldm_pDocument that points at the document object. When a change in the document's data has occurred, the document instructs all of its views to repaint their client area by calling the method UpdateAllViews in order to reflect the change. The message system Windows is built on messages. When the users press one of the mouse buttons or a key, when they resize a window, or when they select a menu item, a message is generated and sent to the current appropriate class. The messages are routed by a message map. The map is generated by the Application Wizard. It can be modified manually or with the Properties Window View (the Messages or Events button). The message map is declared in the file class' header file as follows: DECLARE_MESSAGE_MAP() The message map is implemented in the class' implementation file as follows: BEGIN_MESSAGE_MAP(this_class, base_class)// Message handlers.END_MESSAGE_MAP() Each message has it own handle, and is connected to a method of a specific form that catches the message. There are different handlers for different types of messages. There are around 200 messages in Windows. Here follows a table with the most common ones. Note that we do not have to catch every message. We just catch those we are interested in, the rest will be handled by the framework. Message Handler/Method Sent WM_CREATE ON_WM_CREATE/OnCreate When the window is created, but not yet showed. WM_SIZE ON_WM_SIZE/OnSize When the window has been resized. WM_MOVE ON_WM_MOVE/OnMove When the window has been moved. WM_SETFOCUS ON_WM_SETFOCUS/ OnSetFocus When the window receives input focus. WM_KILLFOCUS ON_WM_KILLFOCUS/ OnKillFocus When the window loses input focus. WM_VSCROLL ON_WM_VSCROLL/ OnVScroll When the user scrolls the vertical bar. WM_HSCROLL ON_WM_HSCROLL/ OnHScroll When the user scrolls the horizontal bar. WM_LBUTTONDOWN   WM_MBUTTONDOWN   WM_RBUTTONDOWN ON_WM_LBUTTONDOWN/ OnLButtonDown ON_WM_MBUTTONDOWN/ OnMButtonDown ON_WM_RBUTTONDOWN/ OnRButtonDown When the user presses the left, middle, or right mouse button. WM_MOUSEMOVE ON_WM_MOUSEMOVE/ OnMouseMove When the user moves the mouse, there are flags available to decide whether the buttons are pressed. WM_LBUTTONUP   WM_MBUTTONUP   WM_RBUTTONUP ON_WM_LBUTTONUP/ OnLButtonUp ON_WM_MUTTONUP/ OnMButtonUp ON_WM_RUTTONUP/ OnRButtonUp When the user releases the left, middle, or right button. WM_CHAR ON_WM_CHAR/OnChar When the user inputs a writable character of the keyboard. WM_KEYDOWN ON_WM_KEYDOWN/ OnKeyDown When the user presses a key of the keyboard. WM_KEYUP ON_WM_KEYUP/ OnKeyUp When the user releases a key of the keyboard. WM_PAINT ON_WM_PAINT/OnPaint When the client area of the window needs to be repainted, partly or completely. WM_CLOSE ON_WM_CLOSE/OnClose When the user clicks at the close button in the upper right corner of the window. WM_DESTROY ON_WM_DESTROY/ OnDestroy When the window is to be closed. WM_COMMAND ON_COMMAND(Identifier, Name)/OnName   When the user selects a menu item, a toolbar button, or a accelerator key connected to the identifier. WM_COMMAND_ UPDATE ON_COMMAND_ UPDATE_UI(Identifier, Name)/OnUpdateName On idle time, when the system is not busy with any other task, this message is sent in order to enable/disable or to check menu items and toolbar buttons. When a user selects a menu item, a command message is sent to the application. Thanks to MFC, the message can be routed to virtually any class in the application. However, in the applications of this article, all menu messages are routed to the document class. It is possible to connect an accelerator key or a toolbar button to the same message, simply by giving it the same identity number. Moreover, when the system is in idle mode (not busy with any other task) thecommand update message is sent to the application. This gives us an opportunity to check or disable some of the menu items. For instance, the Save item in the File menu should be grayed (disabled) when the document has not been modified and does not have to be saved. Say that we have a program where the users can paint in one of three colors. The current color should be marked by a radio box. The message map and its methods can be written manually or be generated with the Resource View (the View menu in Visual Studio) which can help us generate the method prototype, its skeleton definition, and its entry in the message map. The Resource is a system of graphical objects that are linked to the application. When the framework is created by the Application Wizard, the standard menu bar and toolbar are included. We can add our own menus and buttons in Resource Editor, a graphical tool of Visual Studio. The coordinate system In Windows, there are device (physical) and logical coordinates. There are several logical coordinate mapping systems in Windows. The simplest one is the text system; it simply maps one physical unit to the size of a pixel, which means that graphical figures will have different size monitors with different sizes or resolutions. This system is used in the Ring and Tetris applications. The metric system maps one physical unit to a tenth of a millimeter (low metric) or a hundredth of a millimeter (high metric). There is also the British system that maps one physical unit to a hundredth of an inch (low English) or a thousandth of an inch (high English). The British system is not used in this article. The position of a mouse click is always given in device units. When a part of the client area is invalidated (marked for repainting), the coordinates are also given in device units, and when we create or locate the caret, we use device coordinates. Except for these events, we translate the positions into logical units of our choice. We do not have to write translation routines ourselves, there are device context methods LPtoDP (Logical Point to Device Point) and DPtoLP (Device Point to Logical Point) in the next section that do the job for us. The setting of the logical unit system is done in OnInitialUpdate and OnPrepareDC in the view classes. In the Ring and Tetris Applications, we just ignore the coordinates system and use pixels. In the Draw application, the view class is a subclass of the MFC class CScrollView. It has a method SetScrollSizes that takes the logical coordinate system and the total size of the client area (in logical units). Then the mapping between the device and logical system is done automatically and the scroll bars are set to appropriate values when the view is created and each time its size is changed. void SetScrollSizes(int nMapMode, CSize sizeTotal, const CSize& sizePage = sizeDefault, const CSize& sizeLine = sizeDefault); In the Calc and Word Applications, however, we set the mapping between the device and logical system manually by overriding the OnPrepareDC method. It calls the method SetMapMode which sets the logical horizontal and vertical units to be equal. This ensures that circles will be kept round. The MFC device context method GetDeviceCaps returns the size of the screen in pixels and millimeters. Those values are used in the call to SetWindowExt and SetViewportExt, so that the logical unit is one hundredth of a millimeter also in those applications. The SetWindowOrg method sets the origin of the view's client area in relation to the current positions of the scroll bars, which implies that we can draw figures and text without regarding the current positions of the scroll bars. int SetMapMode(int iMapMode);int GetDeviceCaps(int iIndex) const;CSize SetWindowExt(CSize szScreen);CSize SetViewportExt(CSize szScreen);CPoint SetWindowOrg(CPoint ptorigin);
Read more
  • 0
  • 0
  • 1876

article-image-ejb-3-entities
Packt
16 Oct 2009
6 min read
Save for later

EJB 3 Entities

Packt
16 Oct 2009
6 min read
The JPA can be regarded as a higher level of abstraction sitting on top of JDBC. Under the covers the persistence engine converts JPA statements into lower level JDBC statements. EJB 3 Entities In JPA, any class or POJO (Plain Old Java Object) can be converted to an entity with very few modifications. The following listing shows an entity Customer.java with attributes id, which is unique for a Customer instance, and firstName and lastName. package ejb30.entity; import javax.persistence.Entity; import javax.persistence.Id; @Entity public class Customer implements java.io.Serializable { private int id; private String firstName; private String lastName; public Customer() {} @Id public int getId() { return id; } public void setId(int id) { this.id = id; } public String getFirstname() { return firstName; } public void setFirstname(String firstName) { this.firstName = firstName; } public String getLastname() { return lastName; } public void setLastname(String lastName) { this.lastName = lastName; } public String toString() { return "[Customer Id =" + id + ",first name=" + firstName + ",last name=" + lastName + "]"; } } The class follows the usual JavaBean rules. The instance variables are non-public and are accessed by clients through appropriately named getter and setter accessor methods. Only a couple of annotations have been added to distinguish this entity from a POJO. Annotations specify entity metadata. They are not an intrinsic part of an entity but describe how an entity is persisted. The @Entity annotation indicates to the persistence engine that the annotated class, in this case Customer, is an entity. The annotation is placed immediately before the class definition and is an example of a class level annotation. We can also have property-based and field-based annotations, as we shall see. The @Id annotation specifies the primary key of the entity. The id attribute is a primary key candidate. Note that we have placed the annotation immediately before the corresponding getter method, getId(). This is an example of a property-based annotation. A property-based annotation must be placed immediately before the corresponding getter method, and not the setter method. Where property-based annotations are used, the persistence engine uses the getter and setter methods to access and set the entity state. An alternative to property-based annotations are field-based annotations. An example of this is shown later. Note that all annotations within an entity, other than class level annotations, must be all property-based or all field-based. The final requirement for an entity is the presence of a no-arg constructor. Our Customer entity also implements the java.io.Serializable interface. This is not essential, but good practice because the Customer entity has the potential of becoming a detached entity. Detached entities must implement the Serializable interface. At this point we remind the reader that, as throughout EJB 3, XML deployment descriptors are an alternative to entity metadata annotations. Comparison with EJB 2.x Entity Beans An EJB 3 entity is a POJO and not a component, so it is referred to as an entity and not an entity bean. In EJB 2.x the corresponding construct is an entity bean component with the same artifacts as session beans, namely an XML deployment descriptor file, a remote or local interface, a home or localhome interface, and the bean class itself. The remote or local interface contains getter and setter method definitions. The home or local interface contains definitions for the create() and findByPrimaryKey() methods and optionally other finder method definitions. As with session beans, the entity bean class contains callback methods such as ejbCreate(), ejbLoad(), ejbStore(), ejbRemove(), ejbActivate(), ejbPassivate(), and setEntityContext(). The EJB 3 entity, being a POJO, can run outside a container. Its clients are always local to the JVM. The EJB 2.x entity bean is a distributed object that needs a container to run, but can have clients from outside its JVM. Consequently EJB 3 entities are more reusable and easier to test than EJB 2.x entity beans. In EJB 2.x we need to decide whether the persistence aspects of an entity bean are handled by the container (Container Managed Persistence or CMP) or by the application (Bean Managed Persistence or BMP). In the case of CMP, the entity bean is defined as an abstract class with abstract getter and setter method definitions. At deployment the container creates a concrete implementation of this abstract entity bean class. In the case of BMP, the entity bean is defined as a class. The getter and setter methods need to be coded. In addition the ejbCreate(), ejbLoad(), ejbStore(), ejbFindByPrimaryKey(), and any other finder methods need to be coded using JDBC. Mapping an Entity to a Database Table We can map entities onto just about any relational database. GlassFish includes an embedded Derby relational database. If we want GlassFish to access another relational database, Oracle say, then we need to use the GlassFish admin console to set up an Oracle data source. We also need to refer to this Oracle data source in the persistence.xml file. We will describe the persistence.xml file later in this article. These steps are not required if we use the GlassFish default Derby data source. All the examples in this article will use the Derby database. EJB 3 makes heavy use of defaulting for describing entity metadata. In this section we describe a few of these defaults. First, by default, the persistence engine maps the entity name to a relational table name. So in our example the table name is CUSTOMER. If we want to map the Customer entity to another table we will need to use the @Table annotation which we shall see later. By default, property or fields names are mapped to a column name. So ID, FIRSTNAME, and LASTNAME are the column names corresponding to the id, firstname, and lastname entity attributes. If we want to change this default behavior we will need to use the @Column annotation which we shall see later. JDBC rules are used for mapping Java primitives to relational datatypes. So a String will be mapped to VARCHAR for a Derby database and VARCHAR2 for an Oracle database. An int will be mapped to INTEGER for a Derby database and NUMBER for an Oracle database. The size of a column mapped from a String defaults to 255, for example VARCHAR(255) for Derby or VARCHAR2(255) for Oracle. If we want to change this column size then we need to use the length element of the @Column annotation which we shall see later. To summarize, if we are using the GlassFish container with the embedded Derby database, the Customer entity will map onto the following table:   CUSTOMER ID INTEGER PRIMARY KEY FIRSTNAME VARCHAR(255) LASTNAME VARCHAR(255) Most persistence engines, including the GlassFish default persistence engine, Toplink, have a schema generation option, although this is not required by the JPA specification. In the case of GlassFish, if a flag is set when the application is deployed to the container, then the container will create the mapped table in the database. Otherwise the table is assumed to exist in the database.
Read more
  • 0
  • 0
  • 2329

article-image-jboss-portals-and-ajax-part-2
Packt
16 Oct 2009
7 min read
Save for later

JBoss Portals and AJAX - Part 2

Packt
16 Oct 2009
7 min read
AJAX support for markup Special tags are added to layout JSPs that facilitate the placement of AJAX features on a page. Similarly, renderers are used to interpret the tags and to render AJAX-driven content. The obvious advantage is the in-built support for the auto-creation and control of AJAX components on portal pages. Layout markup Layouts provide a structure for the creation and serving of portal pages. Layouts aggregate all of the content generated by the portlet, based on region and order, merge them with some additional content provided by the portal, and serve a response back to the user. By providing support for AJAX in the layout, helps facilitate the easy development and implementation of dynamic functionality in pages, with minimal effort. Layout markup is implemented using JSP tags. The JBoss JSP tag library, portlet-layout.tld, offers tags that facilitate the implementation of AJAX features in layouts. A JSP layout can be changed to an AJAX-supported page simply by adding references to the tags. Hence, using tags also helps with the easy implementation of features. The following is the layout page from the default portal generic layout ${JBOSS_PORTAL_HOME}serverdefaultdeployjboss-portal.sarportal-core.warlayoutsgenericindex.jsp, and shows AJAX support implemented as tags: <%@ page import="org.jboss.portal.server.PortalConstants" %><%@ taglib uri="/WEB-INF/theme/portal-layout.tld" prefix="p" %><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html ><head> <title><%= PortalConstants.VERSION.toString() %></title> <meta http-equiv="Content-Type" content="text/html;"/> <!-- to correct the unsightly Flash of Unstyled Content. --> <script type="text/javascript"></script> <!-- inject the theme, default to the Renaissance theme if nothing is selected for the portal or the page --> <p:theme themeName="renaissance"/> <!-- insert header content that was possibly set by portlets on the page --> <p:headerContent/> <%@include file="/layouts/common/modal_head.jsp"%></head><body id="body"><p:region regionName='AJAXScripts' regionID='AJAXScripts'/><%@include file="/layouts/common/modal_body.jsp"%><div id="portal-container"> <div id="sizer"> <div id="expander"> <div id="logoName"></div> <table border="0" cellpadding="0" cellspacing="0" id="header-container"> <tr> <td align="center" valign="top" id="header"> <!-- Utility controls --> <p:region regionName='dashboardnav' regionID='dashboardnav'/> <!-- navigation tabs and such --> <p:region regionName='navigation' regionID='navigation'/> <div id="spacer"></div> </td> </tr> </table> <div id="content-container"> <!-- insert the content of the 'left' region of the page, and assign the css selector id 'regionA' --> <p:region regionName='left' regionID='regionA'/> <!-- insert the content of the 'center' region of the page, and assign the css selector id 'regionB' --> <p:region regionName='center' regionID='regionB'/> <hr class="cleaner"/> </div> </div> </div></div><div id="footer-container" class="portal-copyright">Powered by <a class="portal-copyright" href="http://www.jboss.com/products/jbossportal">JBoss Portal</a><br/></div><p:region regionName='AJAXFooter' regionID='AJAXFooter'/></body></html> Renderer markup The portal combines the renderers and layouts to generate the final content. Enabling support for AJAX in the renderer just requires adding the statement <ajax-enabled>true</ajax-enabled> to the renderer descriptor. The following example, at {JBOSS_PORTAL_HOME}serverdefaultdeployjbossportal.sarportal-core.warWEB-INFlayoutportal-renderSet.xml, shows the renderer configuration of the emptyRenderer RenderSet for AJAX support: <renderSet name="emptyRenderer"> <set content-type="text/html"> <ajax-enabled>true</ajax-enabled> <region-renderer> org.jboss.portal.theme.impl.render.empty.EmptyRegionRenderer </region-renderer> <window-renderer> org.jboss.portal.theme.impl.render.empty.EmptyWindowRenderer </window-renderer> <portlet-renderer> org.jboss.portal.theme.impl.render.empty.EmptyPortletRenderer </portlet-renderer> <decoration-renderer> org.jboss.portal.theme.impl.render.empty.EmptyDecorationRenderer </decoration-renderer> </set></renderSet> AJAX support for content Whereas the layout and renderer contribute to AJAX behavior at the markup level, JBoss portal's support for object-level configuration can be leveraged to provide AJAX support at the page level. The object property inherits a configured behavior from its parent. Currently, two features are offered for AJAX-driven content: Drag and drop: Facilitates easy movement of portlets to various locations on screen using the mouse. Screen Refresh: Allows sub-components of pages or individual portlets to refresh themselves without refreshing the entire page. Drag-and-Drop As the name suggests, this feature is triggered by a user action, and allows a portlet to detach itself from a specific location on the page and move to a different location on the page. This allows for the customization of the user interface to a form that is most convenient to the user. The dynamic view behavior comes from a combination of DHTML and asynchronous server-side communication. Due to the nature of the behavior, drag-and-drop capability is available and effective only in dashboard pages where there are multiple portlets and the page layout can be personalized. The feature is allowed by default on the dashboard, but can be turned off by setting the value in the configuration file to false. The following is a snippet of the default object configuration file ( jboss-portal.sar/conf/data/default-object.xml ), which illustrates the enabling of the feature. Please note that this can also be configured using the administration console user interface of the JBoss server. <deployment> <if-exists>keep</if-exists> <context> <context-name>dashboard</context-name> <properties> ... <!-- Set the dnd property --> <property> <name>theme.dyna.dnd_enabled</name> <value>true</value> </property> ... </properties> </context></deployment> <name>theme.dyna.dnd_enabled</name> value enables or disables the drag-and-drop behavior. Partial content refresh One of the most expensive processes in a portal is the refresh of portlets when the page is generated. For every user action on a page, the portal calls all of the portlet methods in a serial, but non-specific order, which involves a significant amount of time and server-side processing. Partial content refresh support mitigates these issues to a large extent with an effective use of client-server asynchronous communication. When the state of a single portlet changes, a partial content refresh facilitates the update and refresh of only that portlet, instead of for all of the portlets on the page. This prevents the regeneration of the whole page and the initialization of all of the portlets on the page. The following image illustrates the partial content refresh flow:   The partial refresh capability is compatible with the JSR-168 portlet API, which allows for programmatic update of portlet states during runtime. Partial refreshes can be enabled through portal object configuration or through configuration at the default server level.
Read more
  • 0
  • 0
  • 2066

article-image-human-readable-rules-drools-jboss-rules-50part-2
Packt
16 Oct 2009
5 min read
Save for later

Human-readable Rules with Drools JBoss Rules 5.0(Part 2)

Packt
16 Oct 2009
5 min read
Drools Agenda Before we talk about how to manage rule execution order, we have to understand Drools Agenda. When an object is inserted into the knowledge session, Drools tries to match this object with all of the possible rules. If a rule has all of its conditions met, its consequence can be executed. We say that a rule is activated. Drools records this event by placing this rule onto its agenda (it is a collection of activated rules). As you may imagine, many rules can be activated, and also deactivated, depending on what objects are in the rule session. After the fireAllRules method call, Drools picks one rule from the agenda and executes its consequence. It may or may not cause further activations or deactivations. This continues until the Drools Agenda is empty. The purpose of the agenda is to manage the execution order of rules. Methods for managing rule execution order The following are the methods for managing the rule execution order (from the user's perspective). They can be viewed as alternatives to ruleflow. All of them are defined as rule attributes. salience: This is the most basic one. Every rule has a salience value. By default it is set to 0. Rules with higher salience value will fire first. The problem with this approach is that it is hard to maintain. If we want to add new rule with some priority, we may have to shift the priorities of existing rules. It is often hard to figure out why a rule has certain salience, so we have to comment every salience value. It creates an invisible dependency on other rules. activation-group: This used to be called xor-group. When two or more rules with the same activation group are on the agenda, Drools will fire just one of them. agenda-group: Every rule has an agenda group. By default it is MAIN. However, it can be overridden. This allows us to partition Drools Agenda into multiple groups that can be executed separately. The figure above shows partitioned Agenda with activated rules. The matched rules are coming from left and going into Agenda. One rule is chosen from the Agenda at a time and then executed/fired. At runtime, we can programmatically set the active Agenda group (through the getAgenda().getAgendaGroup(String agendaGroup).setFocus() method of KnowledgeRuntime), or declaratively, by setting the rule attribute auto-focus to true. When a rule is activated and has this attribute set to true, the active agenda group is automatically changed to rule's agenda group. Drools maintains a stack of agenda groups. Whenever the focus is set to a different agenda group, Drools adds this group onto this stack. When there are no rules to fire in the current agenda group, Drools pops from the stack and sets the agenda group to the next one. Agenda groups are similar to ruleflow groups with the exception that ruleflow groups are not stacked. Note that only one instance of each of these attributes is allowed per rule (for example, a rule can only be in one ruleflow-group ; however, it can also define salience within that group). Ruleflow As we've already said, ruleflow can externalize the execution order from the rule definitions. Rules just define a ruleflow-group attribute, which is similar to agenda-group. It is then used to define the execution order. A simple ruleflow (in the example.rf file) is shown in the following screenshot: The preceding screenshot shows a ruleflow opened with the Drools Eclipse plugin. On the lefthand side are the components that can be used when building a ruleflow. On the righthand side is the ruleflow itself. It has a Start node which goes to ruleflow group called Group 1. After it finishes execution, an Action is executed, then the flow continues to another ruleflow group called Group 2, and finally it finishes at an End node. Ruleflow definitions are stored in a file with the .rf extension. This file has an XML format and defines the structure and layout for presentational purposes. Another useful rule attribute for managing which rules can be activated is lock-on-active. It is a special form of the no-loop attribute. It can be used in combination with ruleflow-group or agenda-group. If it is set to true, and an agenda/ruleflow group becomes active/focused, it discards any further activations for the rule until a different group becomes active. Please note that activations that are already on the agenda will be fired. A ruleflow consists of various nodes. Each node has a name, type, and other specific attributes. You can see and change these attributes by opening the standard Properties view in Eclipse while editing the ruleflow file. The basic node types are as follows: Start End Action RuleFlowGroup Split Join They are discussed in the following sections. Start It is the initial node. The flow begins here. Each ruleflow needs one start node. This node has no incoming connection—just one outgoing connection. End It is a terminal node. When execution reaches this node, the whole ruleflow is terminated (all of the active nodes are canceled). This node has one incoming connection and no outgoing connections. Action Used to execute some arbitrary block of code. It is similar to the rule consequence—it can reference global variables and can specify dialect. RuleFlowGroup This node will activate a ruleflow-group, as specified by its RuleFlowGroup attribute. It should match the value in ruleflow-group rule attribute.  
Read more
  • 0
  • 0
  • 5015
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-jquery-ui-accordion-widget-part-1
Packt
16 Oct 2009
9 min read
Save for later

jQuery UI Accordion Widget - Part 1

Packt
16 Oct 2009
9 min read
Accordion's structure Let's take a moment to familiarize ourselves with what an accordion is made of. Within the outer container is a series of links. These links are the headings within the accordion and each heading will have a corresponding content panel, or drawer as they are sometimes referred to, which opens when the heading is clicked. The following screenshot shows these elements as they may appear in an accordion: It's worth remembering that when using the accordion widget, only one content panel can be open at any one time. Let's implement a basic accordion now. In a blank page in your text editor, create the following page: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>jQuery UI Accordion Widget Example 1</title> </head> <body> <ul id="myAccordion"> <li> <a href="#">Header 1</a> <div>Wow, look at all this content that can be shown or hidden with a simple click!</div> </li> <li> <a href="#">Header 2</a> <div>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean sollicitudin. Sed interdum pulvinar justo. Nam iaculis volutpatligula. Integer vitae felis quis diam laoreet ullamcorper. Etiam tincidunt est vitae est. Ut posuere, mauris at sodales rutrum, turpis tellus fermentum metus, ut bibendum velit enim eu lectus. Suspendisse potenti. </div> </li> <li> <a href="#">Header 3</a> <div>Donec at dolor ac metus pharetra aliquam. Suspendisse purus. Fusce tempor ultrices libero. Sed quis nunc. Pellentesque tincidunt viverra felis. Integer elit mauris, egestas ultricies, gravida vitae, feugiat a, tellus.</div> </li> </ul> <script type="text/javascript" src="jqueryui1.6rc2/jquery-1.2.6.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.core.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.accordion.js"></script> <script type="text/javascript"> //function to execute when doc ready $(function() { //turn specified element into an accordion $("#myAccordion").accordion(); }); </script> </body></html> Save the file as accordion1.html in your jqueryui folder and try it out in a browser. We haven't specified any styling at all at this stage, but as you can see from the following screenshot, it still functions exactly as intended: Little code is required for a basic working version of the accordion widget. A simple unordered list element is the mark-up foundation which is transformed by the library into the accordion object. The following three separate external script files are required for an accordion: The jQuery library itself (jquery-1.2.6.js) The UI base file (ui.core.js) The accordion source file (ui.accordion.js) The first two files are mandatory requirements of all components of the UI library. They should be linked to in the order shown here. Each widget also has its own source file, and may depend on other components as well. The order in which these files appear is important. The jQuery library must always appear first, followed by the UI base file. After these files, any other files that the widget depends upon should appear before the widget's own script file. The library components will not function as expected if files are not loaded in the correct order. Finally, we use a custom <script> block to turn our <ul> element into the accordion. We can use the jQuery object shortcut $ to specify an anonymous function which will be executed as soon as the document is ready. This is analogous to using $(document).ready(function(){}) and helps to cut down on the amount of code we have to type. Following this, we use the simple ID selector $("#myAccordion") to specify the element on the page we want to transform. We then use the accordion() constructor method to create the accordion Other elements can be turned into accordions as well. All list element variants are supported including ordered lists and definition lists. You don't even need to base the accordion on a list element at all. You can build a perfectly functional accordion using just nested <div> and <a> elements, although additional configuration will be required In the above example, we used an empty fragment (#) as the value of the href attribute. You should note that any URLs supplied for accordion headers will not be followed when the header is clicked within the accordion when using the default implementation. Styling the accordion With no styling, the accordion will take up 100% of the width of its container. Like with other widgets, we have several options for styling the accordion. We can create our own custom stylesheet to control the appearance of the accordion and its content, we can use the default or flora themes that come with the library, or we can use Theme Roller to create an extensive skin for the whole library. Let's see how using the flora theme for the accordion will cause it to render. In accordion1.html, add the following <link> tag to the <head> of the page: <link rel="stylesheet" type="text/css" href="jqueryui1.6rc2/themes/flora/flora.accordion.css"> Save the new file as accordion2.html, also in the jqueryui folder, and view it again in a browser. It should appear something like this: The accordion theme file assumes that an unordered list is being used as the basis of the widget and specifically targets <li> elements with certain style rules. We can easily create our own custom theme to style the accordion for situations where we want to use a non-list-based accordion widget, or if we simply want different colors or font styles. You can use the excellent Firebug plugin for Firefox, or another DOM viewer, to see the class names that are automatically added to certain elements when the accordion is generated. You can also read through an un-minified version of the source file if you really feel like it. These will be the class names that we'll be targeting with our custom CSS. The following screenshot shows Firebug in action: Change accordion2.html so that it appears as follows (new code is shown in bold): <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html lang="en"> <head> <link rel="stylesheet" type="text/css" href="styles/accordionTheme.css"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>jQuery UI Accordion Widget Example 3</title> </head> <body> <div id="myAccordion"> <span class="corner topLeft"></span><span class="corner topRight"></span><span class="corner bottomLeft"></span><span class="corner bottomRight"></span> <div><a href="#">Header 1</a><div>Wow, look at all this content that can be shown or hidden with a simple click!</div></div> <div><a href="#">Header 2</a><div>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean sollicitudin. Sed interdum pulvinar justo. Nam iaculis volutpatligula. Integer vitae felis quis diam laoreet ullamcorper. Etiam tincidunt est vitae est. Ut posuere, mauris at sodales rutrum, turpis tellus fermentum metus, ut bibendum velit enim eu lectus. Suspendisse potenti.</div></div> <div><a href="#">Header 3</a><div>Donec at dolor ac metus pharetra aliquam. Suspendisse purus. Fusce tempor ultrices libero. Sed quis nunc. Pellentesque tincidunt viverra felis. Integer elit mauris, egestas ultricies, gravida vitae, feugiat a, tellus.</div></div> </div> <script type="text/javascript" src="jqueryui1.6rc2/jquery-1.2.6.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.core.js"></script> <script type="text/javascript" src="jqueryui1.6rc2/ui/ui.accordion.js"></script> <script type="text/javascript"> //function to execute when doc ready $(function() { //turn specified element into an accordion $("#myAccordion").accordion(); }); </script> </body></html> Save this version as accordion3.html in the jqueryui folder. The class name ui-accordion is automatically added to the accordion's container element. Therefore, we can use this as a starting point for most of our CSS selectors. The links that form our drawer headers are given the class ui-accordion-header so we can also target this class name. In a new file, create the following stylesheet: #myAccordion { width:200px; border:2px solid #000000; position:relative; list-style-type:none; padding-left:0;}.ui-accordion-header { text-decoration:none; font-weight:bold; color:#000000; display:block; width:100%; text-align:center;}.ui-accordion div div { font-size:90%;}.ui-accordion a { color:#ffffff; background:url(../img/accordion/header-sprite.gif) repeat-x 0px 0px;}.ui-accordion a.selected { background:url(../img/accordion/header-sprite.gif) repeat-x 0px -22px;}.ui-accordion a:hover { background:url(../img/accordion/header-sprite.gif) repeat-x 0px -44px;}/* container rounded corners */.corner { position:absolute; width:12px; height:13px; background:url(../img/accordion/corner-sprite.gif) no-repeat;}.topLeft { top:-2px; left:-2px; background-position:0px 0px;}.topRight { top:-2px; right:-2px; background-position:0px -13px;}.bottomRight { bottom:-2px; right:-2px; background-position:0px -26px;}.bottomLeft { bottom:-2px; left:-2px; background-position:0px -39px;} Save this file as accordionTheme.css in your styles folder and preview accordion3.html in a browser. We will need a new folder for the images we use in this and subsequent examples. Create a new folder inside the img folder and name it accordion. With just two images, and a few simple style rules, we can drastically change the default appearance of the accordion with our own custom skin as shown in the following screenshot: Configuring accordion The accordion has a range of configurable properties which allow us to easily change the default behaviour of the widget. The following table lists the available properties, their default value, and gives a brief description of their usage:
Read more
  • 0
  • 0
  • 4496

article-image-feeds-facebook-applications
Packt
16 Oct 2009
7 min read
Save for later

Feeds in Facebook Applications

Packt
16 Oct 2009
7 min read
{literal} What Are Feeds? Feeds are the way to publish news in Facebook. As we have already mentioned before, there are two types of feeds in Facebook, News feed and Mini feed. News feed instantly tracks activities of a user's online friends, ranging from changes in relationship status to added photos to wall comments. Mini feed appears on individuals' profiles and highlights recent social activity. You can see your news feed right after you log in, and point your browser to http://www.facebook.com/home.php. It looks like the following, which is, in fact, my news feed. Mini feeds are seen in your profile page, displaying your recent activities and look like the following one: Only the last 10 entries are being displayed in the mini feed section of the profile page. But you can always see the complete list of mini feeds by going to http://www.facebook.com/minifeed.php. Also the mini feed of any user can be accessed from http://www.facebook.com/minifeed.php?id=userid. There is another close relation between news feed and mini feed. When applications publish a mini feed in your profile, it will also appear in your friend's news feed page. How to publish Feeds Facebook provides three APIs to publish mini feeds and news feeds. But these are restricted to call not more than 10 times for a particular user in a 48 hour cycle. This means you can publish a maximum of 10 feeds in a specific user's profile within 48 hours. The following three APIs help to publish feeds: feed_publishStoryToUser—this function publishes the story to the news feed of any user (limited to call once every 12 hours). feed_publishActionOfUser—this one publishes the story to a user's mini feed, and to his or her friend's news feed (limited to call 10 times in a rolling 48 hour slot). feed_publishTemplatizedAction—this one also publishes mini feeds and news feeds, but in an easier way (limited to call 10 times in a rolling 48 hour slot). You can test this API also from http://developers.facebook.com/tools.php?api, and by choosing Feed Preview Console, which will give you the following interface: And once you execute the sample, like the previous one, it will preview the sample of your feed. Sample application to play with Feeds Let's publish some news to our profile, and test how the functions actually work. In this section, we will develop a small application (RateBuddies) by which we will be able to send messages to our friends, and then publish our activities as a mini feed. The purpose of this application is to display friends list and rate them in different categories (Awesome, All Square, Loser, etc.). Here is the code of our application: index.php<?include_once("prepend.php"); //the Lib and key container?><div style="padding:20px;"><?if (!empty($_POST['friend_sel'])){ $friend = $_POST['friend_sel']; $rating = $_POST['rate']; $title = "<fb:name uid='{$fbuser}' useyou='false' /> just <a href='http://apps.facebook.com/ratebuddies/'>Rated</a> <fb:name uid='{$friend}' useyou='false' /> as a '{$rating}' "; $body = "Why not you also <a href='http://apps.facebook.com/ratebuddies/'>rate your friends</a>?";try{//now publish the story to user's mini feed and on his friend's news feed $facebook->api_client->feed_publishActionOfUser($title, $body, null, $null,null, null, null, null, null, null, 1); } catch(Exception $e) { //echo "Error when publishing feeds: "; echo $e->getMessage(); }}?> <h1>Welcome to RateBuddies, your gateway to rate your friends</h1> <div style="padding-top:10px;"> <form method="POST"> Seect a friend: <br/><br/> <fb:friend-selector uid="<?=$fbuser;?>" name="friendid" idname="friend_sel" /> <br/><br/><br/> And your friend is: <br/> <table> <tr> <td valign="middle"><input name="rate" type="radio" value="funny" /></td> <td valign="middle">Funny</td> </tr> <tr> <td valign="middle"><input name="rate" type="radio" value="hot tempered" /></td> <td valign="middle">Hot Tempered</td> </tr> <tr> <td valign="middle"><input name="rate" type="radio" value="awesome" /></td> <td valign="middle">Awesome</td> </tr> <tr> <td valign="middle"><input name="rate" type="radio" value="naughty professor" /></td> <td valign="middle">Naughty Professor</td> </tr> <tr> <td valign="middle"><input name="rate" type="radio" value="looser" /></td> <td valign="middle">Looser</td> </tr> <tr> <td valign="middle"><input name="rate" type="radio" value="empty veseel" /></td> <td valign="middle">Empty Vessel</td> </tr> <tr> <td valign="middle"><input name="rate" type="radio" value="foxy" /></td> <td valign="middle">Foxy</td> </tr> <tr> <td valign="middle"><input name="rate" type="radio" value="childish" /></td> <td valign="middle">Childish</td> </tr> </table> &nbsp; <input type="submit" value="Rate Buddy"/> </form> </div></div> index.php includes another file called prepend.php. In that file, we initialized the facebook api client using the API key and Secret key of the current application. It is a good practice to keep them in separate file because we need to use them throughout our application, in as many pages as we have. Here is the code of that file: prepend.php<?php// this defines some of your basic setupinclude 'client/facebook.php'; // the facebook API library// Get these from ?http://www.facebook.com/developers/apps.phphttp://www.facebook.com/developers/apps.php$api_key = 'your api key';//the api ket of this application$secret = 'your secret key'; //the secret key$facebook = new Facebook($api_key, $secret); //catch the exception that gets thrown if the cookie has an invalid session_key in it try { if (!$facebook->api_client->users_isAppAdded()) { $facebook->redirect($facebook->get_add_url()); } } catch (Exception $ex) { //this will clear cookies for your application and redirect them to a login prompt $facebook->set_user(null, null); $facebook->redirect($appcallbackurl); }?> The client is a standard Facebook REST API client, which is available directly from Facebook. If you are not sure about these API keys, then point your browser to http://www.facebook.com/developers/apps.php and collect the API key and secret key from there. Here is a screenshot of that page: Just collect your API key and Secret Key from this page, when you develop your own application. Now, when you point your browser to http://apps.facebooks.com/ratebuddies and successfully add that application, it will look like this: To see how this app works, type a friend in the box, Select a friend, and click on any rating such as Funny or Foxy. Then click on the Rate Buddy button. As soon as the page submits, open your profile page and you will see that it has published a mini feed in your profile.
Read more
  • 0
  • 0
  • 5373

article-image-arrays-and-control-structures-object-oriented-javascript
Packt
16 Oct 2009
4 min read
Save for later

Arrays and Control Structures in Object-Oriented JavaScript

Packt
16 Oct 2009
4 min read
Arrays Now that you know the basic primitive data types in JavaScript, it's time to move to a more interesting data structure—the array. To declare a variable that contains an empty array, you use square brackets with nothing between them: >>> var a = [];>>> typeof a;"object" typeof returns "object", but don't worry about this for the time being, we'll get to that when we take a closer look at objects. To define an array that has three elements, you do this: >>> var a = [1,2,3]; When you simply type the name of the array in the Firebug console, it prints the contents of the array: >>> a[1, 2, 3] So what is an array exactly? It's simply a list of values. Instead of using one variable to store one value, you can use one array variable to store any number of values as elements of the array. Now the question is how to access each of these stored values? The elements contained in an array are indexed with consecutive numbers starting from zero. The first element has index (or position) 0, the second has index 1 and so on. Here's the three-element array from the previous example: Index Value 0 1 1 2 2 3 In order to access an array element, you specify the index of that element inside square brackets. So a[0] gives you the first element of the array a, a[1] gives you the second, and so on. >>> a[0]1>>> a[1]2 Adding/Updating Array Elements Using the index, you can also update elements of the array. The next example updates the third element (index 2) and prints the contents of the new array. >>> a[2] = 'three';"three">>> a[1, 2, "three"] You can add more elements, by addressing an index that didn't exist before. >>> a[3] = 'four';"four">>> a[1, 2, "three", "four"] If you add a new element, but leave a gap in the array, those elements in between are all assigned the undefined value. Check out this example: >>> var a = [1,2,3];>>> a[6] = 'new';"new">>> a[1, 2, 3, undefined, undefined, undefined, "new"] Deleting Elements In order to delete an element, you can use the delete operator. It doesn't actually remove the element, but sets its value to undefined. After the deletion, the length of the array does not change. >>> var a = [1, 2, 3];>>> delete a[1];true>>> a[1, undefined, 3] Arrays of arrays An array can contain any type of values, including other arrays. >>> var a = [1, "two", false, null, undefined];>>> a[1, "two", false, null, undefined]>>> a[5] = [1,2,3][1, 2, 3]>>> a[1, "two", false, null, undefined, [1, 2, 3]] Let's see an example where you have an array of two elements, each of them being an array. >>> var a = [[1,2,3],[4,5,6]];>>> a[[1, 2, 3], [4, 5, 6]] The first element of the array is a[0] and it is an array itself. >>> a[0][1, 2, 3] To access an element in the nested array, you refer to the element index in another set of square brackets. >>> a[0][0]1>>> a[1][2]6 Note also that you can use the array notation to access individual characters inside a string. >>> var s = 'one';>>> s[0]"o">>> s[1]"n">>> s[2]"e" There are more ways to have fun with arrays, but let's stop here for now, remembering that: An array is a data store An array contains indexed elements Indexes start from zero and increment by one for each element in the array To access array elements we use the index in square brackets An array can contain any type of data, including other arrays
Read more
  • 0
  • 0
  • 5531

article-image-flex-101-flash-builder-4-part-2
Packt
16 Oct 2009
7 min read
Save for later

Flex 101 with Flash Builder 4: Part 2

Packt
16 Oct 2009
7 min read
Using Flash Builder Data Services In this section, we will write the same application that we have written in part one. However this time we will not write the code ourselves instead we'll let the Flash Builder generate the code for us. Flash Builder comes with powerful new features that ease integration with external services. It can auto generate client code that can invoke external services for us and bind the results to existing User Interface components. Let us look at building the same application that we developed in the previous section via the new Data Services and Binding wizardry that Flash Builder provides. Let us create a new Flex Project as shown below: Name this Flex Project as YahooNewsWithDataServices as shown below. We will go with the default settings for the other fields. Click on Finish button. You will get the standard boilerplate code that is produced for the main Application MXML file—YahooNewsWithDataServices.mxml. Switch to the Design View and the Properties tab as shown below. Modify the values for the Layout to spark.layouts.VerticalLayout and the Width and Height to 100%. This means that the main Application window will occupy the maximum area available on your screen and by choosing a Vertical Layout, all visual components dragged to the main Application Canvas will be arranged in a vertical fashion. Stay in Design view. From the Components Tab shown below select Data Controls → DataGrid Drag it onto the canvas on the right side. It will appear as shown below: Keep the DataGrid selected and go to the Properties Tab as shown below. Give it an ID value of dgYahooNews. Set its Width and Height to 100% so that it will occupy the entire parent container like the Application Window. Then click on the Configure Columns button. Clicking on the Configure Columns button will bring up the current columns that are added by default. The screenshot is shown below. We do not need any of these columns at this point. So select each of the columns and click on the Delete button. Finally click on the OK button. Save your work at this point through the Ctrl-S key combination. At this point in time, we will simply create an Application screen with a datagrid on it. Now we need to connect it to the Yahoo News Service and bind the datagrid rows/columns to the data being returned from the Service. In the previous section, we had seen how to do this by writing code. In this case, we will let Flash Builder generate the connectivity code and also do the binding for us. First step is to select the Connect to Data/Service option from the main menu as shown below: This will bring up the wizard as shown in the following screenshot. Flash Builder allows us to connect to several types of backend systems. In our case, we wish to connect to the Yahoo Most Emailed News RSS Service that is available at: http://rss.news.yahoo.com/rss/mostemailed. So we will choose the HTTP Service as shown below and click on the Next button. The next step will be a configuration screen, where we will provide the following information: Service Name: Give the Service a name that you like which u can refer to later. We name it YahooNewsService. Operations: We give an operation name called getNews. The HTTP Method is GET and in the field for URL, you need to provide the RSS Feed URL http://rss.news.yahoo.com/rss/mostemailed You can enter more than one operation name here. Alternately, if you were invoking a HTTP Service using the POST method, you could even specify the Parameters by adding parameters via the Add button.   Click on Finish. This will display a Message window as shown below which tells you that there is still some incomplete work or a few last steps remaining before you can complete the definition of the service and bind it to a UI Component (in our case it is the DataGrid). Click on OK to dismiss the message. Once again, switch to Design view and click on the button for the Data Provider shown below. What we are going to do is associate/bind the result of the Service invocation to the Data Grid via the data provider. This will bring up the Bind To Data window as show below. It should be clear to you by now that we can select the Service and the Operation whose result we wish to bind to our data grid. Flash Builder automatically shows us the Service Name and an Operation name. If there are more Services defined, it will allow to select the appropriate Service and its respective operations. Note that it asks us to Configure Return Type as shown. This is because Flash Builder needs to understand the data that is going to be returned by the Service invocation and also to help it map the result data types to appropriate Action Script Data structures. Click on the Configure Return Type button. This will bring up the Configure Operation Return Type window. Give a name for the Custom Data Type as we have given below and click on the Next button. The next step is to specify the kind of data that will be returned. Flash Builder simplifies this by allowing us to give the complete URL so that it can invoke it and determine the structure that is returned. If you already have a sample response, you could even choose the third option. In our case, we will go with the second option of entering a complete URL as shown below. We also specify the RSS Feed url. Click on the Next button. This will invoke the RSS Feed and retrieve the HTTP Response. Since the response returned is in XML, Flash Builder is able to generically map it to a tree-like structure as shown below. The structure is a typical RSS XML structure. The root node that is rss is shown in the Select Node and all its children nodes are shown in the grid below. Since we are only interested in the RSS items and extracting out the title and category, we first navigate and choose the item field in the Select Node field. This will show all the children nodes for the item field as shown below: Delete all the fields except for title and category. To delete a field, select it and click on the Delete button. Click on the Finish button. This will bring up the original Bind To Data form. Click on the OK button. We are all set now. Save your work and click on the Run button from the main toolbar. Flash Builder will launch the application. The Data Grid on creation will invoke the HTTP Service and the items will be retrieved. The title and category fields are shown for each news item as shown below: r Summary This article provided an introduction to Flex 4 via its development environment Flash Builder. While the applications that we covered in the article are not too practical, it should give you a glimpse of the power of the Flex framework and its tools and loads of developer productivity that is one of its key strengths. Interested readers are encouraged to use this as a starting point in the world of developing Rich Internet Applications with Flex.
Read more
  • 0
  • 0
  • 1492
article-image-extending-document-management-alfresco-3
Packt
16 Oct 2009
5 min read
Save for later

Extending Document Management in Alfresco 3

Packt
16 Oct 2009
5 min read
Microsoft Office 2003 add-ins For Microsoft Windows users, a natural way of working with the files is by using the Microsoft Office tools. It would be a tedious job for Content Managers to have to search and locate the documents using an Alfresco web client, copy them onto their local desktop, edit them, upload them to Alfresco, and secure them. How about having all of the features mentioned above in your choice of editor itself? Alfresco provides Office add-ins for MS Word 2003, MS Excel 2003, and MS PowerPoint 2003, to allow them to manage the content directly from those tools. This improves the productivity of Content Managers. Support for Microsoft Office 2007 Although the Alfresco add-ins were developed for Microsoft Office 2003, they are also compatible with Microsoft Office 2007. If you are using Microsoft Office 2007 on Windows Vista, then the add-in is not effective, as it provides read-only access to the repository. Unfortunately, this is a known problem with Vista, as Microsoft has rewritten the WebDAV parts of Vista. You may consider the workarounds that are provided at the following URL: http://blogs.msdn.com/sharepoint/archive/2007/10/19/known-issue-office-2007-on-windows-vista-prompts-for-user-credentials-when-opening-documents-in-a-sharepoint-2007-site.aspx Installation Download the Alfresco office add-ins (ZIP file) from the source forge web site, by visiting the following URL: http://sourceforge.net/project/showfiles.php?group_id=143373&package_id=237030 An individual installer (for Microsoft Word, Excel, and Power Point), as well as a combined installer, is available for download. Select an appropriate add-into download. Unzip the ZIP file and run the Setup.exe file contained within it. The set-up program will download the components that are needed, from the Microsoft web site. Once the set-up is complete, you can open the Office tool and use the add-in. For example, for MS Word 2003, you will notice a new button named Alfresco. For MS Word 2007, you will notice the add-in, as shown in the following screenshot: Configuration Click on the Alfresco button to open the add-in window. You need to configure the add-in, by clicking on the link provided at the bottom of the add-in window. Provide the URL details for the web client, WebDAV, and CIFS, as shown in the upcoming screenshot. No matter how you access the repository, you will still have to go through Alfresco's security rules. Provide the Userid and password for the purpose of authentication. The access to the Alfresco repository will be based on the authorization of the user. Click on the Save Settings button to go the main screen. If you have more than one Alfresco server to connect to, then you might have to manually change the settings as needed. Currently, there is no facility for storing the settings for more than one Alfresco server. Features of MS Word add-in The Alfresco add-in allows you to carry out the following activities directly from Microsoft Word. Refer to the following screenshot for more details: My Alfresco: Displays the My Alfresco dashlets Browse Spaces: Browses the entire repository for spaces and files. Search: Searches the repository for keywords. View Details: Views the details of the selected document. Workflow: Starts workflow for the active document. Tags: Allows you to add tags to the document. Transform to PDF: Transforms the selected MS Word document into PDF. Insert into Word: Inserts the selected document into Microsoft Word for editing. Save to Alfresco: Saves the current document to the current space. If the document has not been given a filename yet, then a pop-up panel will prompt you for one. Editing a file in Word To edit a file in Microsoft Word, double-click on the file name. The file is opened directly for editing. The MS Word file is locked for others, while it is being edited by you, as shown in the upcoming screenshot. You can perform all of the Alfresco repository activities, such as adding new tags and initiating a workflow approval process. Saving the file in Microsoft Word will directly save it in the Alfresco repository. If auto version is enabled, then it will be versioned automatically. When you close the file in MS Word, or exit from MS Word, the file will be unlocked in the repository. Recovering deleted content When you delete an item (either content or space) in Alfresco, the item is not deleted from the server, but is moved to a temporary store called Archive Space Store. This gives you a chance to recover items that were deleted. Deleted items will be kept in the temporary store forever, until you decide to either recover or purge them. These features are available to administrators through the Manage Deleted Items action. To test these features, log in as an administrator, create a couple of dummy files in any space, and then delete them. Click on the User Profile Icon  option, located above the menu item, and then click on the Manage Deleted Items button. The Manage Deleted Items pane appears, as shown in the following screenshot: You can list all of the deleted content by clicking on the Show All button, as highlighted in the preceding screenshot. You can also search for deleted items by name, by content, by date, or by the person who deleted it, by using the search options provided. Select the item that you previously deleted, and then click on the Recover Listed Items icon, as shown in the preceding screenshot. You will notice that the item is recovered to the original space. When an item is recovered, it is removed from the archive space store and moved to the original space from which it was deleted. Purged items are deleted forever and cannot be recovered. Because the deleted items will otherwise be in the temporary store forever, it is a good practice to purge them periodically. It is also recommended that you take regular backups of your data.  
Read more
  • 0
  • 0
  • 2259

article-image-maintaining-optimizing-and-upgrading-your-site-drupal-6-part-1
Packt
16 Oct 2009
7 min read
Save for later

Maintaining, Optimizing and Upgrading Your Site in Drupal 6: Part 1

Packt
16 Oct 2009
7 min read
We will consider the example of an imaginary web site created for a restaurant called Good Eatin' Bistro. Chef Wanyama is the owner of the Good Eatin' Bistro, a popular upscale restaurant. You can check this web site at http://goodeatin.drupalbyexample.com/. Web site backups A strong backup plan is critical for any successful web site. A good backup plan will protect against hardware failure, allow you to transfer your web site to another host, and allow you to recover from malicious hacking into your web site. When you create a backup plan, you should also test the restoration from this backup to make sure that the backup works correctly. In this section, we will explore ways of performing backups regardless of the host that you are using. Your hosting provider may also offer a solution that will back up files and databases either one time, or on a recurring basis. If your host does provide backup capabilities, you should review them to see if they suit your needs completely, or if you want to augment them or replace them with the techniques in this section. Manually backing up a site Good Eatin' Goal: Back up the web site without using a custom backup module. Additional modules needed: None. Basic steps If you do not want to use a dedicated module to perform your backups, you can manually download the files and the database information that make up the site. However, this can be more time-intensive and error-prone than using a custom backup module. A manual backup has two steps, in which you must first back up the files that make up the site and then back up the database information. To back up the files for the web site, use the following procedure: Begin by opening the utility that you use to transfer files to the web site. This could be an FTP client, or an online file manager. My favorite FTP client is FileZilla, which is a freely-available open source client. The FileZilla client can be downloaded from http://filezilla-project.org/. Select the backup location on your local computer to which you want to copy the files, and select the root directory of your web server as the remote directory. You may want to date the backup folder so that you can maintain a history of the site. Next, download the files to your local directory. If you want, you can compress the files into a ZIP file or a compressed archive. To reduce the amount of data that you need to download, you should be able to download just the sites directory, because that folder contains all of the custom files, pictures, themes, and modules that you have added to the site. To back up the database information, you can use your web site provider's database management utility. Many hosts provide phpMyAdmin for this purpose. If you are unsure whether or not your host gives you access to phpMyAdmin, you can contact their customer support group to check. Begin by opening phpMyAdmin and selecting the database that has your site information within it. The screen should be similar to the following: If you have multiple databases available on the host, you may need to select the database that you want to work with in the drop-down list at the upper left corner of the screen. Next, select the Export tab at the top of the screen. phpMyAdmin will prompt you to select the tables that you want to download and the format that you want to download in, as shown in the following screenshot: If you want to be able to rebuild the database at a later time, you should export all the tables in SQL format. Next, you will need to specify the name of the file to download to. You can use __DB__ as the database name. You may want to zip the file to reduce storage space. Then click Go to begin the download process. You will be prompted for the location to which you want to save the exported data. When you are ready to restore the web site from backup, you simply reverse the process. You should always import into a blank database, to avoid conflicts with existing data. You can either drop or delete all of the titles in the existing database, or you can create a new database to import the data into. After you have cleaned out your database, select the Import tab in phpMyAdmin. Now navigate to the file that you exported earlier, and click Go to begin the import. You may need to delete all of the tables in the database before you import the data, depending on the options you chose when you exported the data. To reload the files, simply open your FTP client, select the same directories that you used when creating the backup and then upload the files, rather than downloading them. Automatic site backups Good Eatin' Goal: Back up a web site so that it can be stored for easy recovery. Additional modules needed: Backup and Migrate (http://drupal.org/project/backup_migrate). Basic steps Although you can manually back up your files and database, this process can be time-consuming and error prone. Luckily, the Backup and Migrate module makes this process easier, and optimizes the backups to exclude unnecessary data. Begin by downloading and installing the Back up and Migrate module. You can now back up your data by selecting Content management and then Backup and migrate, from the Administer menu. The Backup and Migrate module allows you to fully customize the backup files that are created. You can control which tables are included in the backup, and whether or not the data in the table is backed up. By default, the Backup and Migrate module does not back up cache information, session information, or watchdog information, because data in these tables is temporary and can easily be re-created. There are a variety of other options that you can choose from, which control how the resulting file is named, how it is compressed, and where it is compressed to. Once you have set the options as desired, click Backup Database to begin the backup process. If you have selected the Download option, the file will be sent to your computer so that you can store it. If you select the Save to Files Directory option, the backup file will be saved onto the server so that you can download it later, either directly from the server or using the Saved Backups tab. If you would like the Backup and Migrate module to back up your database automatically on a regular basis, you can schedule the back up to occur at specified intervals by clicking on the Backup Schedule tab, as shown here: Please note that the backups created by the Backup and Migrate module do not include the files from the site, so you will still need to back up these files independently. You can minimize the backup file size by only backing up the files that the users can upload. These files are typically stored in the files directory. The process for backing up files is identical to the process used in the section on manual backups. Restoring a site from a backup Good Eatin' Goal: Restore information from a backup file created by the Backup and Migrate module. Additional modules needed: Backup and Migrate (http://drupal.org/project/backup_migrate). Basic steps Restoring a backup created by the Backup and Migrate module is a simple process. Navigate to the Backup and Migrate manager by selecting Content management and then Backup and Migrate, from the Administer menu. Next, click on the Restore/Import DB tab. Navigate to the location of your backup file. After you have selected the backup file, click on Restore Database to begin the restore process. Please read all displayed warnings carefully, and make sure that you test the import on a test installation for your site before running it on your production site. If you are sure that you want to proceed with the import, agree to the confirmation and click restore. You may also need to import any saved files, if the server file system is not fully up-to-date. We discussed this previously in the section on manual backups.
Read more
  • 0
  • 0
  • 1367

article-image-creating-administration-interface-django
Packt
16 Oct 2009
5 min read
Save for later

Creating an Administration Interface in Django

Packt
16 Oct 2009
5 min read
Activating the Administration Interface The administration interface comes as a Django application. To activate it, we will follow a simple procedure that is similar to how we enabled the user authentication system. The admininistration application is located in the django.contrib.admin package. So the first step is adding the path of this package to the INSTALLED_APPS variable. Open settings.py, locate INSTALLED_APPS and edit it as follows: INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.admin', 'django.contrib.comments', 'django_bookmarks.bookmarks',) Next, run the following command to create the necessary tables for the administration application: $ python manage.py syncdb Now we need to make the administration interface accessible from within our site by adding URL entries for it. The administration application defines many views, so manually adding a separate entry for each view can become a tedious task. Therefore, Django provides a shortcut for this. The administration interface defines all of its URL entries in a module located at django.contrib.admin.urls, and we can include these entries in our project under a particular path by using a function called include(). Open urls.py and add the following URL entry to it: urlpatterns = ( # Admin interface (r'^admin/', include('django.contrib.admin.urls')),) This looks different from how we usually define URL entries. We are basically telling Django to retrieve all of the URL entries in the django.contrib.admin.urls module, and to include them in our application under the path ^admin/. This will make the views of the administration interface accessible from within our project. One last thing remains before we see the administration page in action. We need to tell Django what models can be managed in the administration interface. This is done by defining a class called Admin inside each model. Open bookmarks/models.py and add the highlighted section to the Link model: class Link(models.Model): url = models.URLField(unique=True) def __str__(self): return self.url class Admin: pass The Admin class defined inside the model effectively tells Django to enable the Link model in the administration interface. The keyword pass means that the class is empty. Later, we will use this class to customize the administration page, so it won't remain empty. Do the same to the Bookmark, Tag and SharedBookmark models; append an empty class called Admin to each of them. The User model is provided by Django and therefore we don't have control over it. Fortunately however, it already contains an Admin class so it's available in the administration interface by default. Next, launch the development server and direct your browser to http://127.0.0.1:8000/admin/. You will be greeted by a login page. Remember we need to create a superuser account after writing the database model. This is the account that you have to use in order to log in: Next, you will see a list of the models that are available to the administration interface. As discussed earlier, only models with a class named Admin inside them will appear on this page: If you click on a model name, you will get a list of the objects that are stored in the database under this model. You can use this page to view or edit a particular object, or to add a new one. The figure below shows the listing page for the Link model. The edit form is generated according to the fields that exist in the model. The Link form, for example, contains a single text field called Url. You can use this form to view and change the URL of a Link object. In addition, the form performs proper validation of fields before saving the object. So if you try to save a Link object with an invalid URL, you will receive an error message asking you to correct the field. The figure below shows a validation error when trying to save an invalid link: Fields are mapped to form widgets according to their type. Date fields are edited using a calendar widget for example, whereas foreign key fields are edited using a list widget, and so on. The figure below shows a calendar widget from the user edit page. Django uses it for date and time fields: As you may have noticed, the administration interface represents models by using the string returned by the __str__ method. It was indeed a good idea to replace the generic strings returned by the default __str__ method with more helpful ones. This greatly helps when working with the administration page, as well as with debugging. Experiment with the administration pages; try to create, edit and delete objects. Notice how changes made in the administration interface are immediately reflected on the live site. Also, the administration interface keeps track of the actions that you make, and lets you review the history of changes for each object. This section has covered most of what you need to know in order to use the administration interface provided by Django. This feature is actually one of the main advantages of using Django; you get a fully featured administration interface from writing only a few lines of code! Next, we will see how to tweak and customize the administration pages. And as a bonus, we will learn more about the permissions system offered by Django.
Read more
  • 0
  • 0
  • 3073
article-image-oracle-essbase-system-9-components
Packt
16 Oct 2009
7 min read
Save for later

Oracle Essbase System 9 Components

Packt
16 Oct 2009
7 min read
A lot has changed with Essbase since the early days back in the 1990's. Essbase itself has grown and flourished into the world's leading OLAP analytic software and now includes all of the bells and whistles you'd expect and more. The purpose of this article is to go over some exciting new additions to the Essbase family. No longer is it just Essbase, the multidimensional OLAP database. The future of Essbase, beginning with Essbase version 9.x, is now Essbase System 9. Essbase System 9 is now a suite of analytical applications or components of which Essbase is the cornerstone. Some of the components enhance the overall abilities of the suite and some are targeted more to specific computing purposes. Overview of System 9 components When Oracle purchased Hyperion and several other companies, they set out to organize their product catalog and bring together a standardized naming convention as well as standardized software versioning. The Essbase suite of tools and applications is no exception as Essbase version 9.x has become Essbase System 9, and there never really was a commercially released Essbase version 8.x. Oracle now has plans to further integrate the Essbase suite of tools and components into their product catalog and we'll just need to wait and see how this plays out with version 11 and beyond. What we are giving you in this article is a high level look at each new Essbase tool or component and also a slightly lower level look at the hot new additions to the Essbase family. Not to detract from any of the other Essbase family members, but the new Oracle Smart View, for one, is an awesome tool to have in your toolbox. Essbase Analytic Services (Essbase agent) The term Essbase analytic services, while commonly thought to refer to the Essbase suite of applications, actually refers to the common Essbase system structure that is built around the Essbase analytic database engine technology. We know this sounds confusing, but here is how it works. In your Essbase toolbox, you can have many different tools. Some of them are optional and can be added at an additional expense and some of them must be included from the beginning for proper system installation. No matter what tools you want to add to your Essbase toolbox, the Essbase agent or Essbase analytic services must be included and it is the cornerstone of the Essbase suite of applications. The Essbase agent is what you install on your server in order to make it an Essbase analytic server. The Essbase agent is what you use to build, deploy, and maintain your Essbase databases. In a nutshell, Essbase Analytic Services is the heart and soul of your Essbase system. Essbase Planning Also known as Hyperion Planning or even Oracle Planning, Essbase Planning is a centralized Microsoft Excel and web-based planning and forecasting tool that combines data from various internal business activities such as finance, marketing, and so on, into one integrated tool. Planning uses the data to provide a closer look at the company's overall business operations and helps improve the forecast predictability accuracy. Planning makes use of Essbase in an ingenious way. The data for each business activity is stored in its own custom Essbase database or cube. Several business activities can share the same cube and have their own set of dimensions and members. Therefore, Essbase must be started and running in the background so Planning can access the cubes. The various Planning functions are then supported by Planning's seamless accessing of the data from the Essbase cubes and by using the stored business rule feature to apply the customer defined business rules to the data for planning and analysis purposes. The storing of complex business rules to facilitate proper analysis of the data is a huge benefit of Oracle Planning and is accomplished within the module by utilizing a small space on a relational database such as an Oracle or SQL server database. With the aid of pre-packaged process modules, Essbase Planning can also greatly shorten the length of time typically required for budget and forecast cycles, thus lowering the total cost of ownership for this product. Essbase Analytics It's funny, but the word analytics is being tossed about rather often these days.Pretty much anything you do with OLAP or multidimensional database tools,can be termed analytics. In Essbase however, Essbase analytics, to some, usually refers to Essbase's other database engine, the ASO database engine. The reason given for this is that the typical Essbase ASO database is primarily used for presentation, analysis, and reporting which are all analytic functions. The Essbase BSO database, while analytic itself, can also be considered transactional as well. The Essbase analytics nickname dates back to the advent of the ASO database architecture when all you had was the BSO architecture. The new ASO architecture was the analytic tool. Yes, it's funny how Essbase is an analytical package and inside that package is an analytic piece but that's just how it is. Try not to get hung up on the terminology here though. When considering your options, you need to look at all of the same things you have always looked at. How large will the system be? What are the business customer's requirements? What type of system am I building here? When you answer these questions, it will matter less what you call what you are doing than choosing the right tools. Hyperion Application Link/Oracle Application Link The name pretty much says it all. Hyperion Application Link is a suite of ETL tools that allows the user or programmer to integrate Oracle products, like Essbase, with other third party software packages, especially transactional database packages. Hyperion Application Link (HAL) can integrate all of your data loading and ETL functions into one place and offer improved performance. When gathering data for your Essbase application, you may encounter data from many different sources. HAL allows you to set up a link to your favorite Oracle database using an ODBC connection.HAL will also allow you to load data from conveniently delivered flat files too. In fact, you can usually accomplish just about all of your data loading needs for your Essbase System 9 installation by using HAL. Oracle Business Rules This tool can be a tremendous time saver. The Oracle Business Rules tool allows the programmer to create, store, execute, and manage complex business rules as specified by the business customer and as it relates to thebusiness process and the data. All of this is accomplished by using an easy to understand user interface with graphical depictions of the various elements that go into a rule. Imagine a business process that dictates the values for next month's sales commitments as follows: If the actual sales for the prior month are not received by the 15th of the current month, then the committed sales for the current month are to equal the sales number that was forecasted from the prior month If the actual sales for the prior month are received by the 15th, then the number used for the current month's committed sales will be equal to the prior month actual sales * 1.15. This is just one example of a business rule being automatically executed against the data for the users of the system. There are endless possibilities on how to make good use of this tool. The advantages of the Oracle Business Rules tool are clear, especially in today's fast-paced business world where static structures in data load and calculation scripts need almost continual modifying.With the Hyperion Business Rules tool, the dynamic nature of the business can more effectively be supported with the creation of minimal maintenance dynamic rules.
Read more
  • 0
  • 0
  • 2775

article-image-managing-and-enhancing-multi-author-blogs-wordpress-27part-1
Packt
16 Oct 2009
18 min read
Save for later

Managing and Enhancing Multi-Author Blogs with WordPress 2.7(Part 1)

Packt
16 Oct 2009
18 min read
Creating an author page template If you have different authors on your blog, then my suggestion to you would be to display the biographical and contact information of each author on his own dedicated page. Luckily, WordPress allow us to do just that. Getting ready In this recipe, we're going to create an author page template for the purpose of displaying author related information. Make sure that you have understood the creation and usage of a page template. How to do it Create a new file named authors.php on your WordPress theme directory. Insert the following code into your file named authors.php: <?php/*Template Name: Authors Page*/?><?php get_header(); ?><div id="content" class="narrowcolumn"><?phpif(isset($_GET['author_name'])) :$curauth = get_userdatabylogin($author_name);else :$curauth = get_userdata(intval($author));endif;?><h2>About <?php echo $curauth->nickname; ?></h2><div class="excerpt"><?php echo $curauth->nickname; ?> personal website:<a href="<?php echo $curauth->user_url; ?>"><?php echo $curauth->user_url; ?></a></div><?php echo $curauth->user_description; ?><h2>Latest posts by <?php echo $curauth->nickname; ?>:</h2>Chapter 6133<ul><?php if ( have_posts() ) : while ( have_posts() ) :the_post(); ?><li><a href="<?php the_permalink() ?>"><?php the_title();?></a> on <?php the_time('d M Y'); ?></li><?php endwhile; else: ?><p><?php _e('No posts by this author.'); ?></p><?php endif; ?></ul></div><!--/content--><?php get_sidebar(); ?><?php get_footer(); ?> Save the file and upload it to the wp-content/themes/yourtheme folder of your WordPress install. Log in to your WordPress dashboard, create a new page, and select the Authors Page as a page template. Give it the title of your choice, such as, About the Author and publish the page. Open the single.php file from your theme. Depending on the theme that you're using, you may need to add the following code in order to display the author's name and a link to the author's page: Posted by <?php the_author_posts_link(); ?> Once you have saved the modifications made in your single.php file, visit one of your blog posts and click on the author name. The author page is displayed showing the author name, description, and web site. How it works The first thing that we need to know is the name of the author whose information is to be displayed. To do so, we have to get the author_name parameter sent via the GET method. With this value, we can initialize a $curauth php object that will allow us to get some personal information about the author, such as his web site, email, biography, and so on, with the help of the classic php syntax, that is, $curauth->nickname;. Once the author data, that is to be displayed, has been retrieved, we shall add a WordPress loop in order to be able to view the recent posts by this author. The following screenshot shows a well-prepared author page: There's more... In the preceding example we retrieved the author name, description, and web site URL. However, as you may know, users can provide much more information (in Administration, Profile, Your Profile options) such as their email address, AIM and Yahoo! messenger nickname, and login information. A few more template tags can be used to retrieve another kind of information from the author data. These tags are listed under the There's more! section of Displaying author-related information on posts, which we will see later in this article. Displaying a custom login form in your blog's sidebar It doesn't matter whether you're running a multi-author blog, or a blog where readers can register. Having a login form embedded in your sidebar will make your blog look a lot more professional and user friendly. Here is what you can expect from this recipe. In the following screenshot, a login form has been added to the K2 theme sidebar. Getting ready To achieve this recipe, you'll have to edit the sidebar.php file from your theme. The following hack works with WordPress 2.0 to 2.8. How to do it Open the sidebar.php file for editing. Find the opening <ul> tag and paste the following code under it: <li><?php global $user_ID, $user_identity, $user_level ?><?php if ( $user_ID ) : ?><h2><?php echo $user_identity ?></h2><ul><li><a href="<?php bloginfo('url') ?>/wp-login.php?action=logout&amp;redirect_to=<?php echo urlencode($_SERVER['REQUEST_URI']) ?>">Logout</a></li></ul><?php elseif ( get_option('users_can_register') ) : ?>Managing and Enhancing Multi-Author Blogs136<h2>Identification</h2><ul><li><form action="<?php bloginfo('url')?>/wp-login.php" method="post"><p><label for="log"><input type="text" name="log"id="log" value="<?php echo wp_specialchars (stripslashes($user_login), 1) ?>" size="22" /> User</label><br /><label for="pwd"><input type="password"name="pwd" id="pwd" size="22" /> Password</label><br /><input type="submit" name="submit" value="Login"class="button" /><label for="rememberme"><input name="rememberme"id="rememberme" type="checkbox" checked="checked"value="forever" /> Remember me</label><br /></p><input type="hidden" name="redirect_to" value="<?php echo$_SERVER['REQUEST_URI']; ?>"/></form></li><li><a href="<?php bloginfo('url')?>/wp-register.php">Register</a></li><li><a href="<?php bloginfo('url') ?>/wp-login.php?action=lostpassword">Recover password</a></li></ul><?php endif ?></li> Save the file. Your users can now login directly from your blog's sidebar. How it works The working of this code is quite simple. First, you initialize the global variables to get the user ID, name, and level. Then, you check the value of the $user_ID variable. If the value is not null, which means that the current user is logged in, you then display a quick hello user text and a link to log out. If the user isn't logged in, you check whether registering is allowed on the blog. If the user is logged in, then you simply display an HTML form that allows the user to log in directly from the blog. A link has also been included for registration if the current user doesn't have an account yet. This code was inspired from a tutorial available at www.wpdesigner.com. Adding a control panel to your blog's sidebar Now that you have learned how to check whether a user is logged in or not, why not learn how to add a small control panel to your blog's sidebar that is only visible to the logged in users. In this recipe, you'll learn how to achieve this task. Getting ready The upcoming piece of code works in exactly the same way as the code from the previous recipe does. It is all about checking if the user is logged in and whether he or she has the right to do a certain kind of thing. The following screenshot shows a simple, but useful, control panel which is similar to the one we're about to create: How to do it Open sidebar.php for editing. Find the first opening <ul> HTML tag, and paste the following code under the <ul> tag: <li><?php global $user_ID, $user_identity, $user_level ?><?php if ( $user_ID ) : ?><h2>Control panel</h2><ul><li>Identified as <strong><?php echo $user_identity ?></strong>.<ul><li><a href="<?php bloginfo('url') ?>/wp-admin/">Dashboard</a></li><?php if ( $user_level >= 1 ) : ?><li><a href="<?php bloginfo('url') ?>/wp-admin/post-new.php">Write an article</a></li><?php endif; ?><li><a href="<?php bloginfo('url') ?>/wp-admin/profile.php">Profile and personal options</a></li><li><a href="<?php bloginfo('url') ?>/wp-login.php?action=logout&amp;redirect_to=<?php echourlencode($_SERVER['REQUEST_URI']) ?>">Logout</a></li><?phpif (is_single()) {?><li><a href="<?php bloginfo('wpurl');?>/wp-admin/edit.php?p=<?php the_ID(); ?>">Edit Post</a></li><?php } ?></ul></li></ul><?php endif; ?></li> Once you are done, save the file. The allowed users can now go to their dashboard, edit their profile, or write a new post directly from the blog. How it works As mentioned earlier, this code works in the same way as the code that was used to create a login form in the sidebar. After you've made sure that the $user_ID variable isn't null, you work towards displaying the options available to the user. It is possible to define what a user can perform according to his role (administrator, author, contributor, subscriber, and so on). We're going to have a look at this in the next recipe. There's more... Now that you have learned how to add a control panel to the blog's sidebar, let's go ahead and try out something new. Adding a login form and a control panel Now that you know how to add a login form and a mini control panel to your blog's sidebar, why not try mixing the two codes? If the user isn't logged in, we'll display the login form. Otherwise, the custom panel will be shown to the user. The code below works in the same way as the two that we studied previously. Add the following code to the sidebar.php file of your theme: <li><?php global $user_ID, $user_identity, $user_level ?><?php if ( $user_ID ) : ?><h2>Control panel</h2><ul><li>Identified as <strong><?php echo $user_identity ?></strong>.<ul><li><a href="<?php bloginfo('url') ?>/wp-admin/">Dashboard</a></li><?php if ( $user_level >= 1 ) : ?><li><a href="<?php bloginfo('url') ?>/wp-admin/post-new.php">Write an article</a></li><?php endif; ?><li><a href="<?php bloginfo('url') ?>/wp-admin/profile.php">Profile and personal options</a></li><li><a href="<?php bloginfo('url') ?>/wp-login.php?action=logout&amp;redirect_to=<?php echo urlencode($_SERVER['REQUEST_URI']) ?>">Logout</a></li><?phpif (is_single()) {?><li><a href="<?php bloginfo('wpurl');?>/wp-admin/edit.php?p=<?php the_ID(); ?>">Edit Post</a></li><?php } ?></ul></li></ul><?php elseif ( get_option('users_can_register') ) : ?><h2>Identification</h2><ul><li><form action="<?php bloginfo('url') ?>/wp-login.php"method="post"><p><label for="log"><input type="text" name="log" id="log" value="<?php echo wp_specialchars(stripslashes($user_login), 1)?>" size="22" /> User</label><br /><label for="pwd"><input type="password" name="pwd" id="pwd"size="22" /> Password</label><br /><input type="submit" name="submit" value="Login"class="button" /><label for="rememberme"><input name="rememberme" id="rememberme" type="checkbox" checked="checked"value="forever" /> Remember me</label><br /></p><input type="hidden" name="redirect_to" value="<?php echo$_SERVER['REQUEST_URI']; ?>"/></form></li><li><a href="<?php bloginfo('url') ?>/wp-register.php">Register</a></li><li><a href="<?php bloginfo('url') ?>/wp-login.php?action=lostpassword">Recover password</a></li></ul><?php endif; ?></li> The custom logging form for unregistered users will look similar to the following screenshot: And the control panel for logged in users will look similar to the following screenshot: Configuring author roles Now that you have learned about the different aspects of the user's roles and capabilities, there's probably something that you're finding a little frustrating. By default, you can't configure author roles to fit your blog's needs. For example, a contributor can't upload images. Moreover, by default, you can't change it. Luckily, there's a plugin called Role Manager which allows you to configure author roles in the way that you want. Getting ready The Role Manager plugin can be found at the following link: http://www.im-web-gefunden.de/wordpress-plugins/role-manager/ Download it, unzip it onto your hard drive, and install it as any other WordPress plugin. How to do it Once the Role Manager plugin is installed, log in to your WordPress dashboard and go to Users | Roles. A list of all of the available user roles will be displayed. For each role you can define what the user can do. For example, you can choose to let a contributor upload images. What is even better is that you're not limited to the 5 default user roles that are provided by WordPress. The Role Manager plugin allows you to create new roles, as well as the ability to rename, copy, or delete existing ones. How it works The job of the Role Manager plugin is pretty easy. It simply creates custom roles with the options that you have defined and save it on the WordPress database. There's more... Now that we have configured the author roles, let's learn how to control the author's actions. Controlling what authors can do Even if your blog is powered by multiples authors, it is still your blog. Therefore, you shouldn't allow every author to have the right to edit posts or delete comments. Since version 2.0, WordPress features user roles. User roles are defined as a group of actions that can be accomplished by a specific range of users. For example, the administrator can edit theme files, but the subscribers can't. User roles and their capabilities Here are the 5 predefined roles for WordPress users: Administrator: The administrator is the blog owner. He has unlimited access to all of the administration features such as writing posts, editing his own posts along with the posts from other authors, installing plugins, selecting a new theme, editing themes, and editing plugin files. Editor: The editor can write or publish posts, upload images, edit his own posts, and manage other's posts. Author: The author can write, publish, and edit his own his own posts. He's also allowed to upload images for use in his posts. Contributor: A contributor can write posts but can't publish them himself. Once he has written a post, the post is pending approval from the administrator. The contributor can't upload images either. This role is very good for guest authors on your own blog. Subscriber: A subscriber is a registered user of your blog, but can't write posts. For an exhaustive description of user roles and capabilities, you should read the related page in WordPress Codex: http://codex.wordpress.org/Roles_and_Capabilities. Controlling what users can see in your theme In the previous example, we built a sidebar control panel that allows the user to edit the current post. However, the code doesn't let you control which kind of author is allowed to edit the current post. For now, even if only the users with a sufficient role level will be capable of editing the post, every logged in user can see the related link. The solution to that problem is a built-in WordPress function, called current_user_can(). As an argument, this function takes a string describing the action or the required role level to perform a specific task. For example, the following code will provide a link to edit the current post to the administrators only: <?phpif (current_user_can('level_10')){ ?><a href="<?php bloginfo('wpurl');?>/wp-admin/edit.php?p=<?php the_ID(); ?>">Edit Post</a><?php } ?> The current_user_can() function accepts user_0 to user_10 as a parameter. Here is the conversion table between the role levels and the roles: Suscriber: level_0 Contributor: level_1 Author: level_2 to level_4 Editor: level_5 to level_7 Administrator: level_8 to level_10 The current_user_can() function can also be used with a specific action as a parameter. This is the recommended use, as the level parameter is becoming obsolete. The following example checks if the current user can edit a post he previously published. If yes, then a link to edit the post will be displayed. <?phpif (current_user_can('edit_published_posts')){ ?><a href="<?php bloginfo('wpurl');?>/wp-admin/edit.php?p=<?php the_ID(); ?>">Edit Post</a><?php } ?> Here are all of the arguments that are accepted by the current_user_can() function:      switch_themes      edit_themes      activate_plugins      edit_plugins      edit_users      edit_files      manage_options      moderate_comments      manage_categories      manage_links      upload_files      import      unfiltered_html      edit_posts      edit_others_posts      edit_published_posts      edit_pages      edit_others_pages      edit_published_pages      edit_published_pages      delete_pages      delete_others_pages      delete_published_pages      delete_posts      delete_others_posts      delete_published_posts      delete_private_posts      edit_private_posts      read_private_posts      delete_private_pages      edit_private_pages      read_private_pages      delete_users      create_users      unfiltered_upload      edit_dashboard      update_plugins      delete_plugins Displaying author-related information on posts In a multi-author blog, it's always good for the reader to know the author of the article that they're currently reading. It's even better if they can grab some extra information about the author, such as his website, a short bio, and so on. In this recipe, you'll learn how to edit your single.php theme file to automatically retrieve the author-related information, and display it at the top of the page. Getting ready As we're going to display author information on posts, the first thing to do is to make sure that your contributing authors have entered their biography and other information into the WordPress database. Any author can enter his information by logging in to the WordPress dashboard, and then going to Profile. The blog administrator can edit all of the profiles. The following screenshot shows the WordPress 2.7 profile editor for the authors. How to do it Once you have made sure that your authors have successfully filled their information, you can start coding by carrying out the following steps: Open the file single.php for addition. Paste the following code within the loop: <div id="author-info"><h2>About the author: <?php the_author();?></h2><?php the_author_description(); ?><?php the_author();?>'s website: <a href="<?php the_author_url();?>"><?php the_author_url(); ?></a><br />Other posts by <?php the_author_posts_link(); ?></div><!--/author-info--> Save the file and visit your blog. You will notice that your posts now automatically display the author-related information, as shown in the following screenshot: How it works WordPress provides a dozen of author-related template tags, which are an easy way to retrieve information that is entered by authors in their profile. Note that all of these tags must be used within the loop for them to work. There's more... Here are all the available template tags related to authors:
Read more
  • 0
  • 1
  • 2846
Modal Close icon
Modal Close icon