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

How-To Tutorials

7018 Articles
article-image-django-debugging-overview
Packt
28 Apr 2010
9 min read
Save for later

Django Debugging Overview

Packt
28 Apr 2010
9 min read
Django debug settings Django has a number of settings that control the collection and presentation of debug information. The primary one is named DEBUG; it broadly controls whether the server operates in development (if DEBUG is True) or production mode. In development mode, the end-user is expected to be a site developer. Thus, if an error arises during processing of a request, it is useful to include specific technical information about the error in the response sent to the web browser. This is not useful in production mode, when the user is expected to be simply a general site user. This section describes three Django settings that are useful for debugging during development. Additional settings are used during production to control what errors should be reported, and where error reports should be sent. These additional settings will be discussed in the section on handling problems in production. The DEBUG and TEMPLATE_DEBUG settings DEBUG is the main debug setting. One of the most obvious effects of setting this to True is that Django will generate fancy error page responses in the case of serious code problems, such as exceptions raised during processing of a request. If TEMPLATE_DEBUG is also True, and the exception raised is related to a template error, then the fancy error page will also include information about where in the template the error occurred. The default value for both of these settings is False, but the settings.py file created by manage.py startproject turns both of them on by including these lines at the top of the file: DEBUG = True TEMPLATE_DEBUG = DEBUG Note that setting TEMPLATE_DEBUG to True when DEBUG is False isn't useful. The additional information collected with TEMPLATE_DEBUG turned on will never be displayed if the fancy error pages, controlled by the DEBUG setting, are not displayed. Similarly, setting TEMPLATE_DEBUG to False when DEBUG is True isn't very useful. In this case, for template errors, the fancy debug page will be lacking helpful information. Thus, it makes sense to keep these settings tied to each other, as previously shown. Details on the fancy error pages and when they are generated will be covered in the next section. Besides generating these special pages, turning DEBUG on has several other effects. Specifically, when DEBUG is on: A record is kept of all queries sent to the database. Details of what is recorded and how to access it will be covered in a subsequent section. For the MySQL database backend, warnings issued by the database will be turned into Python Exceptions. These MySQL warnings may indicate a serious problem, but a warning (which only results in a message printed to stderr) may pass unnoticed. Since most development is done with DEBUG turned on, raising exceptions for MySQL warnings then ensures that the developer is aware of the possible issue. The admin application performs extensive validation of the configuration of all registered models and raises an ImproperlyConfigured exception on the first attempt to access any admin page if an error is found in the configuration. This extensive validation is fairly expensive and not something you'd generally want done during production server start-up, when the admin configuration likely has not changed since the last start-up. When running with DEBUG on, though, it is possible that the admin configuration has changed, and thus it is useful and worth the cost to do the explicit validation and provide a specific error message about what is wrong if a problem is detected. Finally, there are several places in Django code where an error will occur while DEBUG is on, and the generated response will contain specific information about the cause of the error, whereas when DEBUG is off the generated response will be a generic error page. The TEMPLATE_STRING_IF_INVALID setting A third setting that can be useful for debugging during development is TEMPLATE_STRING_IF_INVALID. The default value for this setting is the empty string. This setting is used to control what gets inserted into a template in place of a reference to an invalid (for example, non-existent in the template context) variable. The default value of an empty string results in nothing visible taking the place of such invalid references, which can make them hard to notice. Setting TEMPLATE_STRING_IF_INVALID to some value can make tracking down such invalid references easier. However, some code that ships with Django (the admin application, in particular), relies on the default behavior of invalid references being replaced with an empty string. Running code like this with a non-empty TEMPLATE_STRING_IF_INVALID setting can produce unexpected results, so this setting is only useful when you are specifically trying to track down something like a misspelled template variable in code that always ensures that variables, even empty ones, are set in the template context. Debug error pages With DEBUG on, Django generates fancy debug error pages in two circumstances: When a django.http.Http404 exception is raised When any other exception is raised and not handled by the regular view processing code In the latter case, the debug page contains a tremendous amount of information about the error, the request that caused it, and the environment at the time it occurred. The debug pages for Http404 exceptions are considerably simpler. To see examples of the Http404 debug pages, consider the survey_detail view def survey_detail(request, pk): survey = get_object_or_404(Survey, pk=pk) today = datetime.date.today() if survey.closes < today: return display_completed_survey(request, survey) elif survey.opens > today: raise Http404 else: return display_active_survey(request, survey) There are two cases where this view may raise an Http404 exception: when the requested survey is not found in the database, and when it is found but has not yet opened. Thus, we can see the debug 404 page by attempting to access the survey detail for a survey that does not exist, say survey number 24. The result will be as follows: Notice there is a message in the middle of the page that describes the cause of the page not found response: No Survey matches the given query. This message was generated automatically by the get_object_or_404 function. By contrast, the bare raise Http404 in the case where the survey is found but not yet open does not look like it will have any descriptive message. To confirm this, add a survey that has an opens date in the future, and try to access its detail page. The result will be something like the following: That is not a very helpful debug page, since it lacks any information about what was being searched for and why it could not be displayed. To make this page more useful, include a message when raising the Http404 exception. For example: raise Http404("%s does not open until %s; it is only %s" % (survey.title, survey.opens, today)) Then an attempt to access this page will be a little more helpful: Note that the error message supplied with the Http404 exception is only displayed on the debug 404 page; it would not appear on a standard 404 page. So you can make such messages as descriptive as you like and not worry that they will leak private or sensitive information to general users. Another thing to note is that a debug 404 page is only generated when an Http404 exception is raised. If you manually construct an HttpResponse with a 404 status code, it will be returned, not the debug 404 page. Consider this code: return HttpResponse("%s does not open until %s; it is only %s" % (survey.title, survey.opens, today), status=404) If that code were used in place of the raise Http404 variant, then the browser will simply display the passed message: Without the prominent Page not found message and distinctive error page formatting, this page isn't even obviously an error report. Note also that some browsers by default will replace the server-provided content with a supposedly "friendly" error page that tends to be even less informative. Thus, it is both easier and more useful to use the Http404 exception instead of manually building HttpResponse objects with status code 404. A final example of the debug 404 page that is very useful is the one that is generated when URL resolution fails. For example, if we add an extra space before the survey number in the URL, the debug 404 page generated will be as follows: The message on this page includes all of the information necessary to figure out why URL resolution failed. It includes the current URL, the name of the base URLConf used for resolution, and all patterns that were tried, in order, for matching. If you do any significant amount of Django application programming, it's highly likely that at some time this page will appear and you will be convinced that one of the listed patterns should match the given URL. You would be wrong. Do not waste energy trying to figure out how Django could be so broken. Rather, trust the error message, and focus your energies on figuring out why the pattern you think should match doesn't in fact match. Look carefully at each element of the pattern and compare it to the actual element in the current URL: there will be something that doesn't match. In this case, you might think the third listed pattern should match the current URL. The first element in the pattern is the capture of the primary key value, and the actual URL value does contain a number that could be a primary key. However, the capture is done using the pattern d+. An attempt to match this against the actual URL characters—a space followed by 2—fails because d only matches numeric digits and the space character is not a numeric digit. There will always be something like this to explain why the URL resolution failed. For now, we will leave the subject of debug pages and learn about accessing the history of database queries that is maintained when DEBUG is on.
Read more
  • 0
  • 0
  • 6943

article-image-walkthrough-tools-within-sketchup-71
Packt
28 Apr 2010
8 min read
Save for later

Walkthrough Tools within SketchUp 7.1

Packt
28 Apr 2010
8 min read
The same principles for stills and animation Creating moving images, or movies for architectural visualization, takes a slightly different but related mindset to still images (stills). That's because an animated sequence shows off more of the scene than in a still. For example, you might see the back of a building which you wouldn't have bothered modeling for a still. Now you have to model it. Here's a recap If you can't see it, it isn't there (don't model it) If it's in the background, make it low poly or a 2D cutout Use interesting and varied camera angles But this time, all this has to be kept in mind for the duration of a 30-second, 5-minute, or even feature length presentation made up of many views of the model. This can quickly become an overwhelming premise. So, we need to do it like all good movie producers do it. And guess what? You already know what that is, and practice it just about every day, because we're simply talking about breaking it down into bite sized chunks. Rome wasn't built in a day Some architect didn't sit down one day and start sketching Rome, starting with the Coliseum and working outwards until he'd finished the whole city. It took ages (literally) and involved many different designers and designs. So, Rome was made up of component parts, and each component part was made up of individual bricks. Just like you do every day with other design projects, home DIY, life goals, or even a holiday itinerary, you're going to break down your animation scene by scene and shot by shot. Making a start: Sketch it out Even if you already have a fully detailed model that you can quite happily view from any angle, you need to start by planning what you want to see in your animation. Actually, that's a complete lie. Why would the client want to see what you want to see? You're interested in buildings for pity's sake! So, we must start by filling the boots of the client or "audience" and from now on only think in terms of their wishes. If there wes a switch to turn them on, what would it be? Time for action – write out your itinerary If you were to visit the quaint English village of Bourton-on-the-Water, what would be the absolute "must sees" of your trip? If you have travelled for 17 days to get there, you knew you could never go back there again, and you were the last one to go with a film camera before it was leveled by hungry bulldozers? So, write out your itinerary. There's a method of doing this that's completely easy and foolproof. You can do it when you're on the train or eating your cornflakes: Take an A3 sheet of paper. Start at the centre of the page and write down a feature of the building you're "selling" to your audience. Rotate the page randomly and write another somewhere in a blank space. Do it again and again Go completely crazy and write down whatever pops into your head (such as "dishwasher", "great drainage", or "south facing"). When you've filled the page, collect them all up in a list. Put three columns down the right-hand side, labeled Quality, Desirability, and a blank column. It doesn't matter if you spell desirability wrong. That's the point of the exercise, no wrong answers, don't worry about spelling or getting the best stuff down. Just get the flow going. When you're done, in the Quality column give a rating 1 to 5 for how "nice" this part of this particular development is: Now do a valley fold to hide the first column. In the Desirability column, give a rating 1 to 5 for how desirable such a building feature is to your audience. You need to divorce this from your particular building completely. Rate it purely on how your audience would view this feature on any building. Does anti-vandal paint on a bin store make someone want to buy a property? When you're done, multiply the first and second column and put the total in the third. What just happened? Without knowing it or finding it remotely difficult, you have written the itinerary for your animation. Easy wasn't it? You probably don't think you've achieved much, but you have. By using this method you were forced to be dispassionate about your design or model. You were also forced to separate out what you like (as a building feature lover) and what your audience wants (as the ones wanti ng to be in it!). What you have in the third column is a definitive rating of the impact of each feature on your audience. Go ahead and label it "impact" now. Generating the story board You are now ready to sketch out the storyboard, because you now know what to include in your animation and what to leave out. Take a pink marker and highlight everything with a score of 20-25. This is your prime real-estate. Take an orange marker and highlight scores of 12-16. And take a yellow marker to all the nines. Nines are just about tolerable. What you now have is a color coded scene allocation system. When deciding what to put into your animation, you should get all the pinks in as many times as you can. You should get the oranges in the rest of the time. And you should use the yellows to pad the content out where necessary and give an overall context to the presentation. And guess what? Anything you've not colored will actually detract from the presentation and stop people buying the property. Don't you dare even model them! Dealing with detractions As you've discovered, anything in your list that didn't get colored could easily detract so much from your presentation that someone who would normally be enamored with it is left cold instead. So, these areas should be minimized if possible, but what do you do if they're a central feature and have to be included for context (or honesty)? For example the electricity enclosure, the bin store, or the plant room? Here's a quick list of ways to overcome this problem: Leave non-critical areas blank and un-textured, giving the context but not the detail Cover or mask with entourage Leave unfocussed in the background (with moving images this only possible when using professional level compositing software) Use viewing angles that obscure these features Probably as much of your effort should be spent in minimizing bad features as promoting good ones. You should aim at showing the development in its best light and greatest potential. Time for action – the storyboard Now that you've decided what needs to be included and what needs to be left out, you need to decide how long to allocate to each, and what the camera views should be. Do the following on paper with sketches. Split up your list into scenes, including wide views and close-up views. Decide how long the whole animation should last. Add a couple of seconds for cutting out later. What about transitions? Are you going to travel from one scene to the next, or cut to it? Work out how long to spend on each scene, each transition. Create a rough sketch for the start of each scene. Scan them into your computer. The following steps are shown specific to Windows Movie Maker, but are similar to all basic video editing software (Adobe Premiere Elements, Final Cut Express, iMovie, or similar) In Windows Movie Maker or similar, import each picture. In Import Pictures hold Ctrl to select more than one then click Import. The pictures will open in the Collections area. Drag them one by one into the StoryBoard in the sequence you want Click Show Timeline. Drag the edge of each image out to the correct time-length. Press play on the preview viewer. Keep adding scene sketches and editing the timing until you're happy. Add voice or music to the audio channel if you want to key the scene transitions to that as follows: Click Import Audio or Music. Navigate to the file, then drag into the storyboard as before. Remember to save the project. What just happened? You just storyboarded your whole animation so that you now know exactly where and what you need to go and model. You did this in Movie Maker or something similar, creating place markers so you can easily import your moving clips later. This saves an enormous amount of time in the long run because you will only model, texture, animate, and render what you're going to see, not what'll get left on the cutting room floor. If you already have your SketchUp scene completed, you could take screenshots from that instead of sketching it out. You can use this later, as a template to insert the actual animations into. When you're doing a complex project such as an animation, it's vital to get a second or third pair of eyes onto it early on. Use your rough and ready movie to talk it through with a colleague, tutor, or a "clued up" friend. It's important to do it at this early stage because you haven't invested lots of time and emotion into it yet.
Read more
  • 0
  • 0
  • 8122

article-image-working-aggregators-oracle-coherence-35
Packt
27 Apr 2010
5 min read
Save for later

Working with Aggregators in Oracle Coherence 3.5

Packt
27 Apr 2010
5 min read
For example, you might want to retrieve the total amount of all orders for a particular customer. One possible solution is to retrieve all the orders for the customer using a filter and to iterate over them on the client in order to calculate the total. While this will work, you need to consider the implications: You might end up moving a lot of data across the network in order to calculate a result that is only few bytes long You will be calculating the result in a single-threaded fashion, which might introduce a performance bottleneck into your application The better approach would be to calculate partial results on each cache node for the data it manages, and to aggregate those partial results into a single answer before returning it to the client. Fortunately, we can use Coherence aggregators to achieve exactly that. By using an aggregator, we limit the amount of data that needs to be moved across the wire to the aggregator instance itself, the partial results returned by each Coherence node the aggregator is evaluated on, and the final result. This reduces the network traffic significantly and ensures that we use the network as efficiently as possible. It also allows us to perform the aggregation in parallel, using full processing power of the Coherence cluster. At the very basic, an aggregator is an instance of a class that implements the com.tangosol.util.InvocableMap.EntryAggregator interface: interface EntryAggregator extends Serializable {Object aggregate(Set set);} However, you will rarely have the need to implement this interface directly. Instead, you should extend the com.tangosol.util.aggregator.AbstractAggregator class that also implements the com.tangosol.util.InvocableMap.ParallelAwareAggregator interface, which is required to ensure that the aggregation is performed in parallel across the cluster. The AbstractAggregator class has a constructor that accepts a value extractor to use and defines the three abstract methods you need to override: public abstract class AbstractAggregatorimplements InvocableMap.ParallelAwareAggregator {public AbstractAggregator(ValueExtractor valueExtractor) {...}protected abstract void init(boolean isFinal);protected abstract void process(Object value, boolean isFinal);protected abstract Object finalizeResult(boolean isFinal);} The init method is used to initialize the result of aggregation, the process method is used to process a single aggregation value and include it in the result, and the finalizeResult method is used to create the final result of the aggregation. Because aggregators can be executed in parallel, the init and finalizeResult methods accept a flag specifying whether the result to initialize or finalize is the final result that should be returned by the aggregator or a partial result, returned by one of the parallel aggregators. The process method also accepts an isFinal flag, but in its case the semantics are somewhat different—if the isFinal flag is true, that means that the object to process is the result of a single parallel aggregator execution that needs to be incorporated into the final result. Otherwise, it is the value extracted from a target object using the value extractor that was specified as a constructor argument. This will all be much clearer when we look at an example. Let's write a simple aggregator that returns an average value of a numeric attribute: public class AverageAggregatorextends AbstractAggregator {private transient double sum;private transient int count;public AverageAggregator() {// deserialization constructor}public AverageAggregator(ValueExtractor valueExtractor) {super(valueExtractor);}public AverageAggregator(String propertyName) {super(propertyName);}protected void init(boolean isFinal) {sum = 0;count = 0;}protected void process(Object value, boolean isFinal) {if (value != null) {if (isFinal) {PartialResult pr = (PartialResult) o;sum += pr.getSum();count += pr.getCount();}else {sum += ((Number) o).doubleValue();count++;}}}protected Object finalizeResult(boolean isFinal) {if (isFinal) {return count == 0 ? null : sum / count;}else {return new PartialResult(sum, count);}}static class PartialResult implements Serializable {private double sum;private int count;PartialResult(double sum, int count) {this.sum = sum;this.count = count;}public double getSum() {return sum;}public int getCount() {return count;}}} As you can see, the init method simply sets both the sum and the count fields to zero, completely ignoring the value of the isFinal flag. This is OK, as we want those values to start from zero whether we are initializing our main aggregator or one of the parallel aggregators. The finalizeResult method, on the other hand, depends on the isFinal flag to decide which value to return. If it is true, it divides the sum by the count in order to calculate the average and returns it. The only exception is if the count is zero, in which case the result is undefined and the null value is returned. However, if the isFinal flag is false, the finalizeResult simply returns an instance of a PartialResult inner class, which is nothing more than a holder for the partial sum and related count on a single node. Finally, the process method also uses the isFinal flag to determine its correct behavior. If it's true, that means that the value to be processed is a PartialResult instance, so it reads partial sum and count from it and adds them to the main aggregator's sum and count fields. Otherwise, it simply adds the value to the sum field and increments the count field by one. We have implemented AverageAggregator in order to demonstrate with a simple example how the isFinal flag should be used to control the aggregation, as well as to show that the partial and the final result do not have to be of the same type. However, this particular aggregator is pretty much a throw-away piece of code, as we'll see in the next section.
Read more
  • 0
  • 0
  • 3070

article-image-working-value-extractors-and-simplifying-queries-oracle-coherence-35
Packt
27 Apr 2010
5 min read
Save for later

Working with Value Extractors and Simplifying Queries in Oracle Coherence 3.5

Packt
27 Apr 2010
5 min read
Coherence allows you to do look up one or more objects based on attributes other than the identity by specifying a filter for set-based operations defined by the QueryMap interface. public interface QueryMap extends Map {Set keySet(Filter filter);Set entrySet(Filter filter);Set entrySet(Filter filter, Comparator comparator);...} As you can see from the previous interface definition, all three methods accept a filter as the first argument, which is an instance of a class implementing a very simple com.tangosol.util.Filter interface: public interface Filter {boolean evaluate(Object o);} Basically, the Filter interface defines a single method, evaluate, which takes an object to evaluate as an argument and returns true if the specified object satisfies the criteria defined by the filter, or false if it doesn't. This mechanism is very flexible, as it allows you to filter your cached objects any way you want. For example, it would be quite simple to implement a filter that can be used to retrieve all the account transactions in a specific period: public class TransactionFilter implements Filter {private Long m_accountId;private Date m_from;private Date m_to;public TransactionFilter(Long accountId, Date from, Date to) {m_accountId = accountId;m_from = from;m_to = to;}public boolean evaluate(Object o) {Transaction tx = (Transaction) o;return tx.getId().getAccountId().equals(m_accountId)&& tx.getTime().compareTo(from) >= 0&& tx.getTime().compareTo(to) <= 0;}} While the previous sample filter implementation is perfectly valid and will return correct results if executed against the transactions cache, it would be very cumbersome if you had to define every single query criterion in the application by implementing a custom filter class as we did previously. Fortunately, Coherence provides a number of built-in filters that make custom filter implementation unnecessary in the vast majority of cases. Built-in filters Most queries can be expressed in terms of object attributes and standard logical and relational operators, such as AND, OR, equals, less than, greater than, and so on. For example, if we wanted to find all the transactions for an account, it would be much easier if we could just execute the query analogous to the select * from Transactions where account_id = 123 SQL statement than to write a custom filter that checks if the accountId attribute is equal to 123. The good news is that Coherence has a number of built-in filters that allow us to do exactly that. The following table lists all the filters from the com.tangosol.util.filter package that you can use to construct custom queries: As you can see, pretty much all of the standard Java logical operators and SQL predicates are covered. This will allow us to construct query expressions as complex as the ones we can define in Java code or the SQL where clause. The bad news is that there is no query language in Coherence that allows you to specify a query as a string. Instead, you need to create the expression tree for the query programmatically, which can make things a bit tedious. For example, the where clause of the SQL statement we specified earlier, select * from Transactions where account_id = 123, can be represented by the following Coherence filter definition: Filter filter = new EqualsFilter("getId.getAccountId", 123); In this case it is not too bad: we simply create an instance of an EqualsFilter that will extract the value of an accountId attribute from a Transaction.Id instance and compare it with 123. However, if we modify the query to filter transactions by date as well, the filter expression that we need to create becomes slightly more complex: Filter filter = new AndFilter(new EqualsFilter("getId.getAccountId", accountId),new BetweenFilter("getTime", from, to)); If you need to combine several logical expressions, this can quickly get out of hand, so we will look for a way to simplify filter creation shortly. But first, let's talk about something we used in the examples without paying much attention to it—value extractors. Value extractors As you can see from the previous examples, a query is typically expressed in terms of object attributes, such as accountId or time, while the evaluate method defined by the Filter interface accepts a whole object that the attributes belong to, such as a Transaction instance. That implies that we need a generic way to extract attribute values from an object instance—otherwise, there would be no way to define reusable filters, such as the ones in the table earlier that ship with Coherence, and we would be forced to implement a custom filter for each query we need to execute. In order to solve this problem and enable extraction of attribute values from an object, Coherence introduces value extractors. A value extractor is an object that implements a com.tangosol.util.ValueExtractor interface: public interface ValueExtractor {Object extract(Object target);} The sole purpose of a value extractor is to extract a derived value from the target object that is passed as an argument to the extract method . The result could be a single attribute value, a combination of multiple attributes (concatenation of first and last name, for example), or in general, a result of some transformation of a target object.
Read more
  • 0
  • 0
  • 5251

article-image-querying-data-grid-coherence-35-obtaining-query-results-and-using-indexes
Packt
27 Apr 2010
6 min read
Save for later

Querying the Data Grid in Coherence 3.5: Obtaining Query Results and Using Indexes

Packt
27 Apr 2010
6 min read
The easiest way to obtain query results is to invoke one of the QueryMap.entrySet methods: Filter filter = ...;Set<Map.Entry> results = cache.entrySet(filter); This will return a set of Map.Entry instances representing both the key and the value of a cache entry, which is likely not what you want. More often than not you need only values, so you will need to iterate over the results and extract the value from each Map.Entry instance: List values = new ArrayList(results.size());for (Map.Entry entry : entries) {values.add(entry.getValue());} After doing this a couple times you will probably want to create a utility method for this task. Because all the queries should be encapsulated within various repository implementations, we can simply add the following utility methods to our AbstractCoherenceRepository class: public abstract class AbstractCoherenceRepository<K, V extendsEntity<K>> {...protected Collection<V> queryForValues(Filter filter) {Set<Map.Entry<K, V>> entries = getCache().entrySet(filter);return extractValues(entries);}protected Collection<V> queryForValues(Filter filter,Comparator comparator) {Set<Map.Entry<K, V>> entries =getCache().entrySet(filter, comparator);return extractValues(entries);}private Collection<V> extractValues(Set<Map.Entry<K, V>> entries) {List<V> values = new ArrayList<V>(entries.size());for (Map.Entry<K, V> entry : entries) {values.add(entry.getValue());}return values;} What happened to the QueryMap.values() method?Obviously, things would be a bit simpler if the QueryMap interface also had an overloaded version of the values method that accepts a filter and optionally comparator as arguments.I'm not sure why this functionality is missing from the API, but I hope it will be added in one of the future releases. In the meantime, a simple utility method is all it takes to provide the missing functionality, so I am not going to complain too much. Controlling query scope using data affinity Data affinity can provide a significant performance boost because it allows Coherence to optimize the query for related objects. Instead of executing the query in parallel across all the nodes and aggregating the results, Coherence can simply execute it on a single node, because data affinity guarantees that all the results will be on that particular node. This effectively reduces the number of objects searched to approximately C/N, where C is the total number of objects in the cache query is executed against, and N is the number of partitions in the cluster. However, this optimization is not automatic—you have to target the partition to search explicitly, using KeyAssociatedFilter: Filter query = ...;Filter filter = new KeyAssociatedFilter(query, key); In the previous example, we create a KeyAssociatedFilter that wraps the query we want to execute. The second argument to its constructor is the cache key that determines the partition to search. To make all of this more concrete, let's look at the final implementation of the code for our sample application that returns account transactions for a specific period. First, we need to add the getTransactions method to our Account class: public Collection<Transaction> getTransactions(Date from, Date to) {return getTransactionRepository().findTransactions(m_id, from, to);} Finally, we need to implement the findTransactions method within the CoherenceTransactionRepository: public Collection<Transaction> findTransactions(Long accountId, Date from, Date to) {Filter filter = new FilterBuilder().equals("id.accountId", accountId).between("time", from, to).build();return queryForValues(new KeyAssociatedFilter(filter, accountId),new DefaultTransactionComparator());} As you can see, we target the query using the account identifier and ensure that the results are sorted by transaction number by passing DefaultTransactionComparator to the queryForValues helper method we implemented earlier. This ensures that Coherence looks for transactions only within the partition that the account with the specified id belongs to. Querying near cache One situation where a direct query using the entrySet method might not be appropriate is when you need to query a near cache. Because there is no way for Coherence to determine if all the results are already in the front cache, it will always execute the query against the back cache and return all the results over the network, even if some or all of them are already present in the front cache. Obviously, this is a waste of network bandwidth. What you can do in order to optimize the query is to obtain the keys first and then retrieve the entries by calling the CacheMap.getAll method: Filter filter = ...;Set keys = cache.keySet(filter);Map results = cache.getAll(keys); The getAll method will try to satisfy as many results as possible from the front cache and delegate to the back cache to retrieve only the missing ones. This will ensure that we move the bare minimum of data across the wire when executing queries, which will improve the throughput. However, keep in mind that this approach might increase latency, as you are making two network roundtrips instead of one, unless all results are already in the front cache. In general, if the expected result set is relatively small, it might make more sense to move all the results over the network using a single entrySet call. Another potential problem with the idiom used for near cache queries is that it could return invalid results. There is a possibility that some of the entries might change between the calls to keySet and getAll. If that happens, getAll might return entries that do not satisfy the filter anymore, so you should only use this approach if you know that this cannot happen (for example, if objects in the cache you are querying, or at least the attributes that the query is based on, are immutable). Sorting the results We have already seen that the entrySet method allows you to pass a Comparator as a second argument, which will be used to sort the results. If your objects implement the Comparable interface you can also specify null as a second argument and the results will be sorted based on their natural ordering. For example, if we defined the natural sort order for transactions by implementing Comparable within our Transaction class, we could've simply passed null instead of a DefaultTransactionComparator instance within the findTransactions implementation shown earlier. On the other hand, if you use near cache query idiom, you will have to sort the results yourself. This is again an opportunity to add utility methods that allow you to query near cache and to optionally sort the results to our base repository class. However, there is a lot more to cover in this article, so I will leave this as an exercise for the reader.
Read more
  • 0
  • 0
  • 1992

article-image-form-validation-codeigniter-17
Packt
26 Apr 2010
8 min read
Save for later

Form Validation with Codeigniter 1.7

Packt
26 Apr 2010
8 min read
Form validation is an important part of any application. Take a look at your favorite web application, notice that there are many forms in these web apps, and it is important that they be secure. It is also important that you have rules that should be adhered to; this also helps to keep a layer of security. In this article by Adam Griffiths, author of CodeIgniter 1.7 Professional Development, you will: Learn how the form validation process works Build a contact form Apply validation rules to the form's input fields Use callbacks to create your own rules We will cover database interaction seperately. (Read more interesting articles on CodeIgniter 1.7 Professional Development here.) Why should I validate my forms? The answer to this question is simple: security. If you simply left your forms bare, with no validation, and then stored this information directly in a database, you are liable to attack. People can simply place in some SQL code and can see a dump of a part or all of your database. By using form validation and creating rules, you will disallow most, if not all, of these practices from occurring. By having set validation rules you can limit the types of data being allowed in your forms. Best of all, the Form Validation Library makes it easy to re-populate your form fields and to show individual errors for each field, making the overall end user experience better; which can mean a lot in an environment with many forms. Even if you are building a contact form, it is a good idea to validate your forms to stop people abusing your form. Using the Form Validation Library In this article, we'll go over a Contact Form and how to use the Form Validation Library methods for validation. The form validation process The Form Validation processes are different for the developers and for users. Read on to see how the user interacts with the forms, as well as how the developer will create the forms. The user's process A form is displayed to the user, who then fills it in and submits it. The Form Validation Library then checks the form against any rules that the developer has set. If an error occurs the library returns these errors and they are shown against the form with the fields re-populated. This process proceeds until a valid form is submitted. The development process You create a form, along with a dynamic value from a form helper function—this will re-populate the data if needed. You will also display individual or global errors in the form view file. You set validation rules, which must be adhered to. Then you check to see if the validation process has been run, and if it has not, you load the form view file. Contact form We validate the form data using the Form Validation Library to complete tasks such as checking for empty fields, validating the e-mail, and then send the e-mail off. All of the code shown should be in the index() function of your email controller. Loading the assets We need to load two libraries for our contact form: the Form Validation Library and the Email class. We can do this in one line, by passing an array to the load->library function. $this->load->library(array('email', 'form_validation')); We also need to load two helpers: the email helper and the form helper. We will do this in the same way as we loaded the two libraries in the previous line of code. $this->load->helper(array('email', 'form')); Setting the rules The next step in using the Form Validation Library is to set the rules for the form. These rules are set and must be adhered to. The way we set rules is by using the set_rules() function of the Form Validation Library. We use the function as follows: $this->form_validation-> set_rules('field_name', 'human_name', 'rules'); As you can see, the function accepts three parameters. The first is the name of the form field that you wish to set the rule for. The second parameter is the name that you wish to be assigned to this, for humans to read. The final parameter is where you pass any validation rules. List of validation rules The following rules are readily available for use: required matches[field_name] min_length[x] max_length[x] exact_length[x] alpha alpha_numeric alpha_dash numeric integer is_natural is_natural_no_zero valid_email valid_emails valid_ip valid_base64 As you can see, some of these rules have a single parameter. The rule matches[] will return TRUE if the field matches the field name passed to it. The min_length[], max_length[], and exact_length[] rules will take an integer as a parameter and check if the minimum length, maximum length respectively, or exact length matches the rule. The rules with no parameters are pretty much self-explanatory. You are able to use more than one rule, simply separate rules with a vertical bar '|' and they will cascade. These rules can also be called as discrete functions. You may also use any native PHP function that accepts one parameter as a rule. $this->form_validation->required($string);$this->form_validation->is_array($string); // native PHP // function as a rule Prepping data We can also use various prepping functions to prep the data before we apply rules to it. Here's a list of the prepping rules that we can perform: xss_clean prep_for_form prep_url strip_image_tags encode_php_tags The first function listed is xss_clean. This basically strips out any code and unwanted characters, and replaces them with HTML entities. The function prep_for_form will convert special characters so that HTML data can be shown in a form without breaking it. The function prep_url will simply add http:// to a URL, if it is missing. The function strip_image_tags will remove image tags, leaving the RAW image URL. The function encode_php_tags will convert PHP tags into entities. You may also use any native PHP function that accepts one parameter as a rule. The rules Now that we know how to set rules and what the rules we can use are, we can go ahead and set the rules necessary for our form. All fields should be required, and the e-mail field should be validated to ensure that the e-mail address is correctly formatted. We also want to run all of the data through the XSS filter. $this->form_validation-> set_rules('name', 'Name', 'required|xss_clean');$this->form_validation-> set_rules('email', 'Email Address', 'required|valid_email|xss_clean');$this->form_validation-> set_rules('subject', 'Subject', 'required|xss_clean');$this->form_validation->set_rules('message', 'Message', 'required|xss_clean'); Check the validation process Instead of checking one of the form field's POST value to check if the form has been submitted, we simply check to see if the Form Validation Library has run. We do this by using the following code: if($this->form_validation->run() === FALSE){ // load the contact form}else // send the email} It's fairly simple: if the Form Validation Library hasn't processed a form, we display the form to the user; if the library has processed a form and there are no errors, we'll send the e-mail off. Sending the email As you'll notice, everything is the same as how we got the field data earlier. $name = $this->input->post('name');$email = $this->input->post('email');$subject = $this->input->post('subject');$message = $this->input->post('message'); $this->email->from($email, $name);$this->email->to('youremail@yourdomain.ext'); $this->email->subject($subject);$this->email->message($message); $this->email->send(); Final controller code Here is the entirety of our controller code: <?phpclass Email extends Controller{function Email(){parent::Controller();} // function Email()function index(){$this->load->library(array('email', 'form_validation'));$this->load->helper(array('email', 'form'));$this->form_validation->set_rules('name', 'Name', 'required|xss_clean');$this->form_validation->set_rules('email', 'Email Address','required|valid_email|xss_clean');$this->form_validation->set_rules('subject', 'Subject', 'required|xss_clean');$this->form_validation->set_rules('message', 'Message', 'required|xss_clean');if($this->form_validation->run() == FALSE){$this->load->view('email'); // load the contact form}else{$name = $this->input->post('name');$email = $this->input->post('email');$subject = $this->input->post('subject');$message = $this->input->post('message');$this->email->from($email, $name);$this->email->to('youremail@yourdomain.ext');$this->email->subject($subject);$this->email->message($message);$this->email->send();}} // function index()} // class Email extends Controller?>
Read more
  • 0
  • 0
  • 4174
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-flash-video-encoding-skinning-and-components-wordpress
Packt
26 Apr 2010
6 min read
Save for later

Flash Video Encoding, Skinning and Components in Wordpress

Packt
26 Apr 2010
6 min read
Encoding with the Adobe Media Encoder If you have a video file, such as an MOV or MP4 file that you want to display as a SWF on the Web, simply encode (or compress) the video file into an FLV. With Flash CS4, you use the Adobe Media Encoder to do this. It can be accessed directly or through Flash's import video function. If you are using an earlier version of Flash, encoding is still possible, and the process is similar. Getting ready Make sure that you have a video file that is compatible with the Adobe Media Encoder. If you do not have a file to use, by all means, use the short.mov file. This file is a clip of the full length summer.mp4 file from www.archive.org that is listed on that website as being in the Public Domain. Use the MOV file because it is a short file, so the time it takes the encoder to render the video will be shorter. This is good for the purposes of learning and practicing. Also, do not worry if you cannot hear any of the sounds. There is nothing wrong with the speakers on your computer. This file does not have audio. How to do it... Open the Adobe Media Encoder: Click on the Add button. Navigate to the file you want to encode, such as short.move, and click on Choose/OK. It is now listed in the queue: Click on the down arrow under Format to select into which file format you will encode the video. Choose FLV | F4V if not already selected. Click on the down arrow under Preset to choose one of the preset export setting options. The default of FLV - Same As Source (Flash 8 and Higher) is generally fine. If you have fewer standard video needs, make a different choice based on your needs. Also, there is an option to Edit Export Settings as well as a Settings button if you want to make your own decisions. See the Edit Export Settings section for more on that. Click on the file name under Output File to select the destination of your encoded file. You can also change the file name. Click on Start Queue, and the encoding process will begin. If you are encoding a long video, you might want to go take a walk or get a cup of tea. For short.mov, just sit tight. It should only take a minute or two to encode. Once encoding is complete, the FLV is saved in the location you chose under the Output File section. There is also a check mark under the encoder's Status section. Now, you can do what you want with the file. For instance, you can take it into Flash and import it into an SWF. How it works... The Adobe Media Encoder encodes the selected video file into the FLV format. It is similar to taking a Photoshop file or a TIFF and compressing either of them into a JPG. The process is simply more involved because the data is more complex. There's more... The Adobe Media Encoder has many options and capabilities. Among these is a wealth of export settings that can be edited to suit your needs. Also available to you is the ability to not only encode multiple files in one sitting but also to duplicate and remove files in your queue. Edit Export Settings With your file selected in the encoder, click on the Settings button. This gives you the Export Settings dialog box: As you can see, it has a lot of options. Only some of the myriad of options will be discussed below. At the top left of the dialog box are two buttons: Source and Output. Source shows the video file you have selected. Output shows a preview of the encoded version of the file. On the bottom/middle left of the Export Settings dialog box, you can address the timeline. You are able to clip the movie if you want to export only part of it; and you can set up cue points. To clip the movie, do the following: Drag the playback head back and forth to manually preview the movie. This helps you find the section you want to keep. Drag the in and out point triangles back and forth to isolate the section you want to keep. The triangle on the left is the in point, and the one on the right is the out point. Everything between the two triangles will be encoded. The timer keeps track of time in milliseconds. The right side of the dialog box allows you to change the desired file format; save your own preset with the button that looks like a computer disk circa 1996. You can also change the file name of the encoded video and choose if you are exporting only video, only audio, or both. The Summary section gives you just that, a summary of your choices thus far. The bottom right section gives you options for putting on a blur filter under the Filter tab and changing the format as applicable under the Format tab. The Video tab lets you choose which Codec to use to encode the video. On2 VP6 is usually the best choice. Stick with that one. It is more advanced, gives better quality, and allows you to encode an Alpha Channel if you have one to encode. Alpha Channels, areas of transparency in video (i.e., green screen), cannot be set up in Flash. They must be set up in a video editing program such as Premiere Pro or Final Cut Pro. The encoder can only honor them, not generate them. If you need to resize your video, check the box for Resize Video, and change the values as needed. If you want to constrain the proportions of your video, leave the chain whole. Frame rate can also be changed here. Generally, it is in your best interest to leave the video set to the same frame rate it was shot in. Same as source is a good choice. For Bitrate Settings, the defaults are usually pretty good. If you want higher quality and can take the additional file size, you can change Encoding Passes to Two. For Advanced Settings, you can change overall quality by selecting either Quality for Speed, Good, or Best. It all depends on your needs. For Audio, if you have it incorporated into your video file, choose Stereo. It sounds better. The only reason to go with Mono is if you have little sound, if it is a video of a talking head, or if your file size needs to be as small as possible. For Bitrate Settings for audio, 128 kb per second is good. Again, only turn this lower if the audio is overly simple, not important, or your file size dictates it. Faster bitrate/higher number gives you better quality sound. When you are finished making changes, click on OK. This gets you back to the encoder. Proceed from here as needed.
Read more
  • 0
  • 0
  • 2042

article-image-packt-open-source-and-packt-enterprise-have-launched
Packt
26 Apr 2010
1 min read
Save for later

Packt Open Source and Packt Enterprise Have Launched

Packt
26 Apr 2010
1 min read
In order to celebrate this launch, and to mark this red-letter day, Packt is offering 20% off the cover price of all its hard copy books, and 30% off the cover price of all eBooks for the duration of the week, ending midday GMT on Monday the 3rd of May. Simply login and add the books of your choice to your basket to redeem this offer. What's more, the eBooks of Microsoft Office Live Small Business: Beginner's Guide and Qmail Quickstarter: Install, Set Up and Run Your Own Email Server have been made free, allowing all those who login to an account on www.PacktPub.com to download them. If you would like to understand more about why Packt has launched these new brands, and how it will impact books, the company and, most importantly, readers, have a look at the new Packt blog, at http://blog.PacktPub.com.    
Read more
  • 0
  • 0
  • 2216

article-image-data-manipulation-silverlight-4-data-grid
Packt
26 Apr 2010
9 min read
Save for later

Data Manipulation in Silverlight 4 Data Grid

Packt
26 Apr 2010
9 min read
Displaying data in a customized DataGrid Displaying data is probably the most straightforward task we can ask the DataGrid to do for us. In this recipe, we'll create a collection of data and hand it over to the DataGrid for display. While the DataGrid may seem to have a rather fixed layout, there are many options available on this control that we can use to customize it. In this recipe, we'll focus on getting the data to show up in the DataGrid and customize it to our likings. Getting ready In this recipe, we'll start from an empty Silverlight application. The finished solution for this recipe can be found in the Chapter04/Datagrid_Displaying_Data_Completed folder in the code bundle that is available on the Packt website. How to do it... We'll create a collection of Book objects and display this collection in a DataGrid. However,we want to customize the DataGrid. More specifically, we want to make the DataGridfixed. In other words, we don't want the user to make any changes to the bound data or move the columns around. Also, we want to change the visual representation of the DataGrid by changing the background color of the rows. We also want the vertical column separators to be hidden and the horizontal ones to get a different color. Finally, we'll hook into the LoadingRow event, which will give us access to the values that are bound to a row and based on that value, the LoadingRow event will allow us to make changes to the visual appearance of the row. To create this DataGrid, you'll need to carry out the following steps: Start a new Silverlight solution called DatagridDisplayingData in Visual Studio. We'll start by creating the Book class. Add a new class to the Silverlight project in the solution and name this class as Book. Note that this class uses two enumerations—one for the Category and the other for the Language. These can be found in the sample code. The following is the code for the Book class: public class Book { public string Title { get; set; } public string Author { get; set; } public int PageCount { get; set; } public DateTime PurchaseDate { get; set; } public Category Category { get; set; } public string Publisher { get; set; } public Languages Language { get; set; } public string ImageName { get; set; } public bool AlreadyRead { get; set; } } In the code-behind of the generated MainPage.xaml file, we need to create a generic list of Book instances (List) and load data into this collection.This is shown in the following code: private List<Book> bookCollection; public MainPage() { InitializeComponent(); LoadBooks(); } private void LoadBooks() { bookCollection = new List<Book>(); Book b1 = new Book(); b1.Title = "Book AAA"; b1.Author = "Author AAA"; b1.Language = Languages.English; b1.PageCount = 350; b1.Publisher = "Publisher BBB"; b1.PurchaseDate = new DateTime(2009, 3, 10); b1.ImageName = "AAA.png"; b1.AlreadyRead = true; b1.Category = Category.Computing; bookCollection.Add(b1); ... } Next, we'll add a DataGrid to the MainPage.xaml file. For now, we won't add any extra properties on the DataGrid. It's advisable to add it to the page by dragging it from the toolbox, so that Visual Studio adds the correct references to the required assemblies in the project, as well as adds the namespace mapping in the XAML code. Remove the AutoGenerateColumns="False" for now so that we'll see all the properties of the Book class appear in the DataGrid. The following line of code shows a default DataGrid with its name set to BookDataGrid: <sdk:DataGrid x_Name="BookDataGrid"></sdk:DataGrid> Currently, no data is bound to the DataGrid. To make the DataGrid show the book collection, we set the ItemsSource property from the code-behind in the constructor. This is shown in the following code: public MainPage() { InitializeComponent(); LoadBooks(); BookDataGrid.ItemsSource = bookCollection; } Running the code now shows a default DataGrid that generates a column for each public property of the Book type. This happens because the AutoGenerateColumns property is True by default. Let's continue by making the DataGrid look the way we want it to look. By default, the DataGrid is user-editable, so we may want to change this feature. Setting the IsReadOnly property to True will make it impossible for a user to edit the data in the control. We can lock the display even further by setting both the CanUserResizeColumns and the CanUserReorderColumns properties to False. This will prohibit the user from resizing and reordering the columns inside the DataGrid, which are enabled by default. This is shown in the following code: <sdk:DataGrid x_Name="BookDataGrid" AutoGenerateColumns="True" CanUserReorderColumns="False" CanUserResizeColumns="False" IsReadOnly="True"> </sdk:DataGrid> The DataGrid also offers quite an impressive list of properties that we can use to change its appearance. By adding the following code, we specify alternating the background colors (the RowBackground and AlternatingRowBackground properties), column widths (the ColumnWidth property), and row heights (the RowHeight property). We also specify how the gridlines should be displayed (the GridLinesVisibility and HorizontalGridLinesBrushs properties). Finally, we specify that we also want a row header to be added (the HeadersVisibility property ). <sdk:DataGrid x_Name="BookDataGrid" AutoGenerateColumns="True" CanUserReorderColumns="False" CanUserResizeColumns="False" RowBackground="#999999" AlternatingRowBackground="#CCCCCC" ColumnWidth="90" RowHeight="30" GridLinesVisibility="Horizontal" HeadersVisibility="All" HorizontalGridLinesBrush="Blue"> </sdk:DataGrid> We can also get a hook into the loading of the rows. For this, the LoadingRow event has to be used. This event is triggered when each row gets loaded. Using this event, we can get access to a row and change its properties based on custom code. In the following code, we are specifying that if the book is a thriller, we want the row to have a red background: private void BookDataGrid_LoadingRow(object sender, DataGridRowEventArgs e) { Book loadedBook = e.Row.DataContext as Book; if (loadedBook.Category == Category.Thriller) { e.Row.Background = new SolidColorBrush(Colors.Red); //It's a thriller! e.Row.Height = 40; } else { e.Row.Background = null; } } After completing these steps, we have the DataGrid that we wanted. It displays the data (including headers), fixes the columns and makes it impossible for the user to edit the data. Also, the color of the rows and alternating rows is changed, the vertical grid lines are hidden, and a different color is applied to the horizontal grid lines. Using the LoadingRow event, we have checked whether the book being added is of the "Thriller" category, and if so, a red color is applied as the background color for the row. The result can be seen in the following screenshot: How it works... The DataGrid allows us to display the data easily, while still offering us many customization options to format the control as needed. The DataGrid is defined in the System.Windows.Controls namespace, which is located in the System.Windows.Controls.Data assembly. By default, this assembly is not referenced while creating a new Silverlight application. Therefore, the following extra references are added while dragging the control from the toolbox for the first time: System.ComponentModel.DataAnnotations System.Windows.Controls.Data System.Windows.Controls.Data.Input System.Windows.Data While compiling the application, the corresponding assemblies are added to the XAP file (as can be seen in the following screenshot, which shows the contents of the XAP file). These assemblies need to be added because while installing the Silverlight plugin, they aren't installed as a part of the CLR. This is done in order to keep the plugin size small. However, when we use them in our application, they are embedded as part of the application. This results in an increase of the download size of the XAP file. In most circumstances, this is not a problem. However, if the file size is an important requirement, then it is essential to keep an eye on this. Also, Visual Studio will include the following namespace mapping into the XAML file: From then on, we can use the control as shown in the following line of code: <sdk:DataGrid x_Name="BookDataGrid"> </sdk:DataGrid> Once the control is added on the page, we can use it in a data binding scenario. To do so, we can point the ItemsSource property to any IEnumerable implementation. Each row in the DataGrid will correspond to an object in the collection. When AutoGenerateColumns is set to True (the default), the DataGrid uses a refl ection on the type of objects bound to it. For each public property it encounters, it generates a corresponding column. Out of the box, the DataGrid includes a text column, a checkbox column, and a template column. For all the types that can't be displayed, it uses the ToString method and a text column. If we want the DataGrid to feature automatic synchronization, the collection should implement the INotifyCollectionChanged interface. If changes to the objects are to be refl ected in the DataGrid, then the objects in the collection should themselves implement the INotifyPropertyChanged interface. There's more While loading large amounts of data into the DataGrid, the performance will still be very good. This is the result of the DataGrid implementing UI virtualization, which is enabled by default. Let's assume that the DataGrid is bound to a collection of 1,000,000 items (whether or not this is useful is another question). Loading all of these items into memory would be a time-consuming task as well as a big performance hit. Due to UI virtualization, the control loads only the rows it's currently displaying. (It will actually load a few more to improve the scrolling experience.) While scrolling, a small lag appears when the control is loading the new items. Since Silverlight 3, the ListBox also features UI virtualization. Inserting, updating, and deleting data in a DataGrid The DataGrid is an outstanding control to use while working with large amounts of data at the same time. Through its Excel-like interface, not only can we easily view the data, but also add new records or update and delete existing ones. In this recipe, we'll take a look at how to build a DataGrid that supports all of the above actions on a collection of items. Getting ready This recipe builds on the code that was created in the previous recipe. To follow along with this recipe, you can keep using your code or use the starter solution located in the Chapter04/Datagrid_Editing_Data_Starter folder in the code bundle available on the Packt website. The finished solution for this recipe can be found in the Chapter04/Datagrid_Editing_Data_Completed folder.
Read more
  • 0
  • 0
  • 6188

article-image-database-interaction-codeigniter-17
Packt
26 Apr 2010
4 min read
Save for later

Database Interaction with Codeigniter 1.7

Packt
26 Apr 2010
4 min read
(Read more interesting articles on CodeIgniter 1.7 Professional Development here.) Loading the library Loading the Database library is slightly different from loading other libraries. This is because it is large and resides in a different folder, unlike the other libraries. $this->load->database(); Performing simple queries Let's dive straight in by starting with the simple stuff. CodeIgniter gives us a function that we can pass a SQL Query to, and the query will be run on the database. Here's how it works: $this->db->query('PUT YOUR SQL HERE'); This function is incredibly simple to use; you simply use this function in place of any native PHP functions you would use to run queries. This function will return TRUE or FALSE for write queries, and will return a dataset for read queries. There is another function that you can use for very simple queries; this will only return TRUE or FALSE. It won't let you cache your query or run the query timer. In most cases you won't want to use this function. $this->db->simple_query('PUT YOUR SQL HERE'); The SQL code that you pass to these functions are database-dependent. Only Active Record queries are independent of any type of Database SQL. Returning values You can assign the function $this->db->query() to a variable. You can then run a number of helper functions on the variable in order to return the data in different formats. Take the following example: $query = $this->db->query('SELECT * FROM 'users''); Return a result object In this case, returning the result will return an array of objects, or an empty array if the query failed. You would usually use this function in a foreach loop. foreach($query->result() as $row){ echo $row->username; echo $row->email;} If your query does not return a result, the CodeIgniter User Guide encourages you to check for a failure before using this function. if($query->num_rows > 0){ foreach($query->result() as $row) { echo $row->username; echo $row->email; }} Returning a result array You are also able to return the result dataset as an array. Typically, you would use this function inside a foreach loop as well. foreach($query->result_array() as $row){ echo $row['username']; echo $row['email'];} Returning a row object If your query is only expected to return a single result, you should return the row by using the following function. The row is returned as an object. if($query->num_rows() > 0){$row = $query->row();echo $row->username;echo $row->email;} You can return a specific row by passing the row number as a digit in the first parameter. $query->row(2); Returning a row array You can return a row as an array, if you prefer. The function is used in the same way as the previous example. if($query->num_rows() > 0){ $row = $query->row_array(); echo $row['username']; echo $row['email'];} You can return a numbered row by passing the digit to the first parameter, also. $query->row_array(2); Result helper functions Besides the helper function that helps to return the dataset in different ways, there are some other more generalized helper functions. Number of rows returned Used in the same way as the other helper functions, this will return the total number of rows returned from a query. Take the following example: echo $query->num_rows(); Number of fields returned Just like the previous function, this will return the number of fields returned by your query. echo $query->num_fields(); Free result This function will remove the resource ID associated with your query, and free the associated memory. PHP will usually do this by default, although when using many queries you may wish to use this to free up memory space. $query->free_result();
Read more
  • 0
  • 0
  • 2561
article-image-creating-wcf-service-business-object-and-data-submission-silverlight-4
Packt
23 Apr 2010
10 min read
Save for later

Creating a WCF Service, Business Object and Data Submission with Silverlight 4

Packt
23 Apr 2010
10 min read
Data applications When building applications that utilize data, it is important to start with defining what data you are going to collect and how it will be stored once collected. In the last chapter, we created a Silverlight application to post a collection of ink strokes to the server. We are going to expand the inkPresenter control to allow a user to submit additional information. Most developers would have had experience building business object layers, and with Silverlight we can still make use of these objects, either by using referenced class projects/libraries or by consuming WCF services and utilizing the associated data contracts. Time for action – creating a business object We'll create a business object that can be used by both Silverlight and our ASP.NET application. To accomplish this, we'll create the business object in our ASP.NET application, define it as a data contract, and expose it to Silverlight via our WCF service. Start Visual Studio and open the CakeORamaData solution. When we created the solution, we originally created a Silverlight application and an ASP.NET web project. In the web project, add a reference to the System.Runtime.Serialization assembly. Right-click on the web project and choose to add a new class. Name this class ServiceObjects and click OK. In the ServiceObjects class file, replace the existing code with the following code: using System; using System.Runtime.Serialization; namespace CakeORamaData.Web { [DataContract] public class CustomerCakeIdea { [DataMember] public string CustomerName { get; set; } [DataMember] public string PhoneNumber { get; set; } [DataMember] public string Email { get; set; } [DataMember] public DateTime EventDate { get; set; } [DataMember] public StrokeInfo[] Strokes { get; set; } } [DataContract] public class StrokeInfo { [DataMember] public double Width { get; set; } [DataMember] public double Height { get; set; } [DataMember] public byte[] Color { get; set; } [DataMember] public byte[] OutlineColor { get; set; } [DataMember] public StylusPointInfo[] Points { get; set; } } [DataContract] public class StylusPointInfo { [DataMember] public double X { get; set; } [DataMember] public double Y { get; set; } } } What we are doing here is defining the data that we'll be collecting from the customer. What just happened? We just added a business object that will be used by our WCF service and our Silverlight application. We added serialization attributes to our class, so that it can be serialized with WCF and consumed by Silverlight. The [DataContract] and [DataMember] attributes are the serialization attributes that WCF will use when serializing our business object for transmission. WCF provides an opt-in model, meaning that types used with WCF must include these attributes in order to participate in serialization. The [DataContract] attribute is required, however if you wish to, you can use the [DataMember] attribute on any of the properties of the class. By default, WCF will use the System.Runtime.Serialization.DataContractSerialzer to serialize the DataContract classes into XML. The .NET Framework also provides a NetDataContractSerializer which includes CLR information in the XML or the JsonDataContractSerializer that will convert the object into JavaScript Object Notation (JSON). The WebGet attribute provides an easy way to define which serializer is used. For more information on these serializers and the WebGet attribute visit the following MSDN web sites: http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.aspx. http://msdn.microsoft.com/en-us/library/system.runtime.serialization.netdatacontractserializer.aspx. http://msdn.microsoft.com/en-us/library/system.runtime.serialization.json.datacontractjsonserializer.aspx. http://msdn.microsoft.com/en-us/library/system.servicemodel.web.webgetattribute.aspx. Windows Communication Foundation (WCF) Windows Communication Foundation (WCF) provides a simplified development experience for connected applications using the service oriented programming model. WCF builds upon and improves the web service model by providing flexible channels in which to connect and communicate with a web service. By utilizing these channels developers can expose their services to a wide variety of client applications such as Silverlight, Windows Presentation Foundation and Windows Forms. Service oriented applications provide a scalable and reusable programming model, allowing applications to expose limited and controlled functionality to a variety of consuming clients such as web sites, enterprise applications, smart clients, and Silverlight applications. When building WCF applications the service contract is typically defined by an interface decorated with attributes that declare the service and the operations. Using an interface allows the contract to be separated from the implementation and is the standard practice with WCF. You can read more about Windows Communication Foundation on the MSDN website at: http://msdn.microsoft.com/en-us/netframework/aa663324.aspx. Time for action – creating a Silverlight-enabled WCF service Now that we have our business object, we need to define a WCF service that can accept the business object and save the data to an XML file. With the CakeORamaData solution open, right-click on the web project and choose to add a new folder, rename it to Services. Right-click on the web project again and choose to add a new item. Add a new WCF Service named CakeService.svc to the Services folder. This will create an interface and implementation files for our WCF service. Avoid adding the Silverlight-enabled WCF service, as this adds a service that goes against the standard design patterns used with WCF: The standard design practice with WCF is to create an interface that defines the ServiceContract and OperationContracts of the service. The interface is then provided, a default implementation on the server. When the service is exposed through metadata, the interface will be used to define the operations of the service and generate the client classes. The Silverlight-enabled WCF service does not create an interface, just an implementation, it is there as a quick entry point into WCF for developers new to the technology. Replace the code in the ICakeService.cs file with the definition below. We are defining a contract with one operation that allows a client application to submit a CustomerCakeIdea instance: using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.Text; namespace CakeORamaData.Web.Services { // NOTE: If you change the interface name "ICakeService" here, you must also update the reference to "ICakeService" in Web.config. [ServiceContract] public interface ICakeService { [OperationContract] void SubmitCakeIdea(CustomerCakeIdea idea); } } The CakeService.svc.cs file will contain the implementation of our service interface. Add the following code to the body of the CakeService.svc.cs file to save the customer information to an XML file: using System; using System.ServiceModel.Activation; using System.Xml; namespace CakeORamaData.Web.Services { // NOTE: If you change the class name "CakeService" here, you must also update the reference to "CakeService" in Web.config. [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class CakeService : ICakeService { public void SubmitCakeIdea(CustomerCakeIdea idea) { if (idea == null) return; using (var writer = XmlWriter.Create(String.Format(@"C: ProjectsCakeORamaCustomerData{0}.xml", idea.CustomerName))) { writer.WriteStartDocument(); //<customer> writer.WriteStartElement("customer"); writer.WriteAttributeString("name", idea.CustomerName); writer.WriteAttributeString("phone", idea.PhoneNumber); writer.WriteAttributeString("email", idea.Email); // <eventDate></eventDate> writer.WriteStartElement("eventDate"); writer.WriteValue(idea.EventDate); writer.WriteEndElement(); // <strokes> writer.WriteStartElement("strokes"); if (idea.Strokes != null && idea.Strokes.Length > 0) { foreach (var stroke in idea.Strokes) { // <stroke> writer.WriteStartElement("stroke"); writer.WriteAttributeString("width", stroke.Width. ToString()); writer.WriteAttributeString("height", stroke.Height. ToString()); writer.WriteStartElement("color"); writer.WriteAttributeString("a", stroke.Color[0]. ToString()); writer.WriteAttributeString("r", stroke.Color[1]. ToString()); writer.WriteAttributeString("g", stroke.Color[2]. ToString()); writer.WriteAttributeString("b", stroke.Color[3]. ToString()); writer.WriteEndElement(); writer.WriteStartElement("outlineColor"); writer.WriteAttributeString("a", stroke. OutlineColor[0].ToString()); writer.WriteAttributeString("r", stroke. OutlineColor[1].ToString()); writer.WriteAttributeString("g", stroke. OutlineColor[2].ToString()); writer.WriteAttributeString("b", stroke. OutlineColor[3].ToString()); writer.WriteEndElement(); if (stroke.Points != null && stroke.Points.Length > 0) { writer.WriteStartElement("points"); foreach (var point in stroke.Points) { writer.WriteStartElement("point"); writer.WriteAttributeString("x", point. X.ToString()); writer.WriteAttributeString("y", point. Y.ToString()); writer.WriteEndElement(); } writer.WriteEndElement(); } // </stroke> writer.WriteEndElement(); } } // </strokes> writer.WriteEndElement(); //</customer> writer.WriteEndElement(); writer.WriteEndDocument(); } } } } We added the AspNetCompatibilityRequirements attribute to our CakeService implementation. This attribute is required in order to use a WCF service from within ASP.NET. Open Windows Explorer and create the path C:ProjectsCakeORamaCustomerData on your hard drive to store the customer XML files. One thing to note is that you will need to grant write permission to this directory for the ASP.NET user account when in a production environment. When adding a WCF service through Visual Studio, binding information is added to the web.config file. The default binding for WCF is wsHttpBinding, which is not a valid binding for Silverlight. The valid bindings for Silverlight are basicHttpBinding, binaryHttpBinding (implemented with a customBinding), and netTcpBinding. We need to modify the web.config, so that Silverlight can consume the service. Open the web.config file and add this customBinding section to the <system.serviceModel> node: <bindings> <customBinding> <binding name="customBinding0"> <binaryMessageEncoding /> <httpTransport> <extendedProtectionPolicy policyEnforcement="Never" /> </httpTransport> </binding> </customBinding> </bindings> We'll need to change the <service> node in the web.config to use our new customBinding, (we use the customBinding to implement binary HTTP which sends the information as a binary stream to the service), rather than the wsHttpbinding from: <service behaviorConfiguration="CakeORamaData.Web.Services. CakeServiceBehavior" name="CakeORamaData.Web.Services.CakeService"> <endpoint address="" binding="wsHttpBinding" contract="CakeORamaData.Web.Services.ICakeService"> <identity> <dns value="localhost" /> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IM etadataExchange" /> </service> To the following: <service behaviorConfiguration="CakeORamaData.Web.Services. CakeServiceBehavior" name="CakeORamaData.Web.Services.CakeService"> <endpoint address="" binding="customBinding" bindingConfiguratio n="customBinding0" contract="CakeORamaData.Web.Services.ICakeService" /> <endpoint address="mex" binding="mexHttpBinding" contract="IMeta dataExchange" /> </service> Set the start page to the CakeService.svc file, then build and run the solution. We will be presented with the following screen, which lets us know that the service and bindings are set up correctly: Our next step is to add the service reference to Silverlight. On the Silverlight project, right-click on the References node and choose to Add a Service Reference: On the dialog that opens, click the Discover button and choose the Services in Solution option. Visual Studio will search the current solution for any services: Visual Studio will find our CakeService and all we have to do is change the Namespace to something that makes sense such as Services and click the OK button: We can see that Visual Studio has added some additional references and files to our project. Developers used to WCF or Web Services will notice the assembly references and the Service References folder: Silverlight creates a ServiceReferences.ClientConfig file that stores the configuration for the service bindings. If we open this file, we can take a look at the client side bindings to our WCF service. These bindings tell our Silverlight application how to connect to the WCF service and the URL where it is located: <configuration> <system.serviceModel> <bindings> <customBinding> <binding name="CustomBinding_ICakeService"> <binaryMessageEncoding /> <httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"> <extendedProtectionPolicy policyEnforcemen t="Never" /> </httpTransport> </binding> </customBinding> </bindings> <client> <endpoint address="http://localhost:2268/Services/ CakeService.svc" binding="customBinding" bindingConfiguration="Cust omBinding_ICakeService" contract="Services.ICakeService" name="CustomBinding_ICakeService" /> </client> </system.serviceModel> </configuration>
Read more
  • 0
  • 0
  • 3189

article-image-moodle-19-theme-design-customizing-header-and-footer-part-1
Packt
23 Apr 2010
7 min read
Save for later

Moodle 1.9 Theme Design: Customizing the Header and Footer (Part 1)

Packt
23 Apr 2010
7 min read
So, let's get on with it... Important preliminary points In order to continue with the exercises in the article, you will need to understand the importance of web browser compatibility. All web browsers are different, and most of them handle HTML and Cascading Style Sheets (CSS) differently. It is not so much that one web browser is better than another or that one web browser is more accurate at rendering HTML or CSS. Rather, it's that CSS rules are often interpreted differently by software developers who designed these browsers. For web developers and designers, this can be very annoying, but an unfortunate and inevitable reality. So, to make sure that the changes that you make to Moodle's theme files are the same or similar across most of the major web browsers, you will need to install various web browsers, such as Firefox, Internet Explorer, Chrome, Opera, Safari, and so on, and make sure that you remember to test your changes. You shall learn to install the required web browsers as you work through this article. Customizing the header One of the first tasks that you will be asked to do concerning Moodle theming is to customize the main Moodle header file. Most people start by learning to change the Moodle logo for one of their own. The file that you will be editing in the first part of this article is the header.html file. For this article, you will assume the standard theme that comes with Moodle. Time for action – making a copy of the standard theme In this exercise, you will be making a copy of the standard theme so that you can make changes to it without interfering with Moodle's theming process. You need to do this because many of the Moodle themes use the standard theme as the base theme. Navigate to the folder: C:Program FilesApache Software FoundationApache 2.2htdocstheme. Right-click on the standard theme folder and choose Copy, as seen in the following screenshot: Right-click again in some empty space and choose Paste. The copied standard theme will be replicated and have the name Copy of standard, as seen below: Right-click on this folder and choose Rename to rename the folder to mytheme. What just happened? You have just made a copy of the standard theme that comes with Moodle and have relocated and renamed the theme, so you can now make some basic changes without interfering with any other themes in the theme directory. Most themes use the standard theme as the parent theme and then build upon this styled theme. So, if you were to change this theme directly, you would probably mess up most of the themes that are installed in your Moodle site. Adding your own logo Now that you have made a copy of the standard theme, you will go on and replace the Moodle logo with your own. Most oft en, your organization will have a logo that you can use; perhaps you could just copy one from their website. An important point to note here is that the logo that you use should be in the GIF or .png format. The following figure has been created with Adobe Photoshop to demonstrate that it would be best to create a very basic logo if you don't have one. Time for action – copying your logo to your mytheme directory Navigate to the location of your logo. Right-click and choose Copy. Navigate to your Moodle site's thememythemepix directory, right-click, and choose Paste. The result should resemble the following screenshot: What just happened? In this very simple exercise, you have copied the logo that you had or created and placed it in the correct directory in your new mytheme directory. This is now ready for you to use in the header.html file to display your logo. Now you will edit the main header.html file to include your new logo. The header.html file can be found in your site's thememytheme directory. Time for action – adding the logo code to your header.html file Navigate to your mytheme directory, right-click on the header.html file, and choose Open With | WordPad. Open the header.html file with your favorite text editor (WordPad, Notepad, Vim, and so on). As a Windows shortcut, you can right-click on the header.html file and choose Open With | WordPad, as seen below: Top Tip – Text editorsWe have chosen WordPad here as it retains the original markup format. Notepad, on the other hand, can be difficult to use, as it lacks some of the functionalities of WordPad. If you already use another text or HTML editor, then please use it. It's about familiarity here, so it's always best to use that with which you feel comfortable. Find the following lines of code: <?php print_container_start(true, '', 'header-home'); ?> <h1 class="headermain"><?php echo $heading ?></h1> <div class="headermenu"><?php echo $menu ?></div><?php print_container_end(); ?> Insert the following line of code: <img src="<?php echo $CFG->themewww .'/'. current_theme() ?>/pix/logo.gif" alt="Institutions Logo" /> Immediately after: <h1 class="headermain"> As shown here: <?php print_container_start(true, '', 'header-home'); ?> <h1 class="headermain"> <img src="<?php echo $CFG->themewww .'/'. current_theme() ?>/pix/logo.gif" alt="Institutions Logo" /> <?php echo $heading ?></h1> <div class="headermenu"><?php echo $menu ?></div><?php print_container_end(); ?> You can download this code from the Packt website. Save and close header.html. Open your web browser and type in the URL of your local Moodle site. Change the current theme, which should be Autumn, to your theme by navigating to Appearance | Themes | Theme Selector and choosing mytheme. You should see something similar to the following screenshot but with your own logo. What just happened? In this exercise, we have learned where a theme's header.html file is and how to open the header.html file for editing. We also learned what part of the code we should change in order to have our own logo appear on the front page of out Moodle site. Have a go hero – adding another logo Again, it's time for you to have a go yourself at changing and modifying some of the things that you have learned through this article. First, it would be a good idea if you would try to create a new logo and add it to the header.html file in your mytheme folder. This time leave the inner page header as it is. Top Tip – Two headersDuring this exercise, you may have noticed that the header.html file has two instances of the following line of code: <h1 class="headermain">. This is because Moodle loads a slightly different header depending on whether you are on the front page or any other page within the site. This means that the changes we have made will only be visible on the front page and not on any other page at the moment. Why don't you go and check this by opening your local Moodle site and clicking on the Logout link in the top right-hand corner and then clicking the Login link in the same place? This will take you to the login front page of Moodle and you will notice that your logo isn't where it is supposed to be. In most situations, we would want to have our logo on all pages within our Moodle site, so we will have to replicate the last exercise and paste our logo code in the other instance of <h1 class="headermain">.
Read more
  • 0
  • 0
  • 2066

article-image-creating-data-forms-silverlight-4
Packt
23 Apr 2010
4 min read
Save for later

Creating Data Forms in Silverlight 4

Packt
23 Apr 2010
4 min read
Collecting data Now that we have created a business object and a WCF service here-http://www.packtpub.com/article/creating-wcf-service-business-object-data-submission-silverlight, we are ready to collect data from the customer through our Silverlight application. Silverlight provides all of the standard input controls that .NET developers have come to know with Windows and ASP.NET development, and of course the controls are customizable through styles. Time for action – creating a form to collect data We will begin by creating a form in Silverlight for collecting the data from the client. We are going to include a submission form to collect the name, phone number, email address, and the date of event for the person submitting the sketch. This will allow the client (Cake O Rama) to contact this individual and follow up on a potential sale. We'll change the layout of MainPage.xaml to include a form for user input. We will need to open the CakeORama project in Expression Blend and then open MainPage.xaml for editing in the Blend art board. Our Ink capture controls are contained within a Grid, so we will just add a column to the Grid and place our input form right next to the Ink surface. To add columns in Blend, select the Grid from the Objects and Timeline panel, position your mouse in the highlighted area above the Grid and click to add a column: Blend will add a <Grid.ColumnDefinitions> node to our XAML: <Grid.ColumnDefinitions><ColumnDefinition Width="0.94*"/><ColumnDefinition Width="0.06*"/></Grid.ColumnDefinitions> Blend also added a Grid.ColumnSpan="2" attribute to both the StackPanel and InkPresenter controls that were already on the page. We need to modify the StackPanel and inkPresenter, so that they do not span both columns and thereby forcing us to increase the size of our second column. In Blend, select the StackPanel from the Objects and Timeline panel: In the Properties panel, you will see a property called ColumnSpan with a value of 2. Change this value to 1 and press the Enter key. We can see that Blend moved the StackPanel into the first column, and we now have a little space next to the buttons. We need to do the same thing to the inkPresenter control, so that it is also within the first column. Select the inkPresenter control from the Objects and Timeline panel: Change the ColumnSpan from 2 to 1 to reposition the inkPresenter into the left column: The inkPresenter control should be positioned in the left column and aligned with the StackPanel containing our ink sketch buttons: Now that we have moved the existing controls into the first column, we will change the size of the second column, so that we can start adding our input controls. We also need to change the overall size of the MainPage.xaml control to fit more information on the right side of the ink control. Click on the [UserControl] in the Objects and Timeline panel, and then in the Properties panel change the Width to 800: Now we need to change the size of our grid columns. We can do this very easily in XAML, so switch to the XAML view in Blend by clicking on the XAML icon: In the XAML view, change the grid column settings to give both columns an equal width: <Grid.ColumnDefinitions><ColumnDefinition Width="0.5*"/><ColumnDefinition Width="0.5*"/></Grid.ColumnDefinitions> Switch back to the design view by clicking on the design button: Our StackPanel and inkPresenter controls are now positioned to the left of the page and we have some empty space to the right for our input controls: Select the LayoutRoot control in the Objects and Timeline panel and then doubleclick on the TextBlock control in the Blend toolbox to add a new TextBlock control: Drag the control to the top and right side of the page: On the Properties panel, change the Text of the TextBlock to Customer Information, change the FontSize to 12pt and click on the Bold indicator:
Read more
  • 0
  • 0
  • 1609
article-image-data-validation-silverlight-4
Packt
23 Apr 2010
7 min read
Save for later

Data Validation in Silverlight 4

Packt
23 Apr 2010
7 min read
With Silverlight, data validation has been fully implemented, allowing controls to be bound to data objects and those data objects to handle the validation of data and provide feedback to the controls via the Visual State Machine. The Visual State Machine is a feature of Silverlight used to render to views of a control based on its state. For instance, the mouse over state of a button can actually change the color of the button, show or hide parts of the control, and so on. Controls that participate in data validation contain a ValidationStates group that includes a Valid, InvalidUnfocused, and InvalidFocused states. We can implement custom styles for these states to provide visual feedback to the user. Data object In order to take advantage of the data validation in Silverlight, we need to create a data object or client side business object that can handle the validation of data. Time for action – creating a data object We are going to create a data object that we will bind to our input form to provide validation. Silverlight can bind to any properties of an object, but for validation we need to do two way binding, for which we need both a get and a set accessor for each of our properties. In order to use two way binding, we will need to implement the INotifyPropertyChanged interface that defines a PropertyChanged event that Silverlight will use to update the binding when a property changes. Firstly, we will need to switch over to Visual Studio and add a new class named CustomerInfo to the Silverlight project: Replace the body of the CustomerInfo.cs file with the following code: using System;using System.ComponentModel;namespace CakeORamaData{ public class CustomerInfo : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged =delegate { }; private string _cutomerName = null; public string CustomerName { get { return _cutomerName; } set { if (value == _cutomerName) return; _cutomerName = value; OnPropertyChanged("CustomerName"); } } private string _phoneNumber = null; public string PhoneNumber { get { return _phoneNumber; } set { if (value == _phoneNumber) return; _phoneNumber = value; OnPropertyChanged("PhoneNumber"); } } private string _email = null; public string Email { get { return _email; } set { if (value == _email) return; _email = value; OnPropertyChanged("Email"); } } private DateTime _eventDate = DateTime.Now.AddDays(7); public DateTime EventDate { get { return _eventDate; } set { if (value == _eventDate) return; _eventDate = value; OnPropertyChanged("EventDate"); } } private void OnPropertyChanged(string propertyName) { PropertyChanged(this, new PropertyChangedEventArgs (propertyName)); } }} Code Snippets Code snippets are a convenient way to stub out repetitive code and increase productivity, by removing the need to type a bunch of the same syntax over and over. The following is a code snippet used to create properties that execute the OnPropertyChanged method and can be very useful when implementing properties on a class that implements the INotifyPropertyChanged interface. To use the snippet, save the file as propnotify.snippet to your hard drive. In Visual Studio go to Tools | Code Snippets Manager (Ctrl + K, Ctrl + B) and click the Import button. Find the propnotify.snippet file and click Open, this will add the snippet. To use the snippet in code, simply type propnotify and hit the Tab key; a property will be stubbed out allowing you to change the name and type of the property. <?xml version="1.0" encoding="utf-8" ?><CodeSnippets > <CodeSnippet Format="1.0.0"> <Header> <Title>propnotify</Title> <Shortcut>propnotify</Shortcut> <Description>Code snippet for a property that raises the PropertyChanged event in a class.</Description> <Author>Cameron Albert</Author> <SnippetTypes> <SnippetType>Expansion</SnippetType> </SnippetTypes> </Header> <Snippet> <Declarations> <Literal> <ID>type</ID> <ToolTip>Property type</ToolTip> <Default>int</Default> </Literal> <Literal> <ID>property</ID> <ToolTip>Property name</ToolTip> <Default>MyProperty</Default> </Literal> <Literal> <ID>field</ID> <ToolTip>Private field</ToolTip> <Default>_myProperty</Default> </Literal> <Literal> <ID>defaultValue</ID> <ToolTip>Default Value</ToolTip> <Default>null</Default> </Literal> </Declarations> <Code Language="csharp"> <![CDATA[private $type$ $field$ = $defaultValue$; public $type$ $property$ { get { return $field$; } set { if (value == $field$) return; $field$ = value; OnPropertyChanged("$property$"); } } $end$]]> </Code> </Snippet> </CodeSnippet></CodeSnippets> What just happened? We created a data object or client-side business object that we can use to bind to our input controls. We implemented the INotifyPropertyChanged interface, so that our data object can raise the PropertyChanged event whenever the value of one of its properties is changed. We also defined a default delegate value for the PropertyChanged event to prevent us from having to do a null check when raising the event. Not to mention we have a nice snippet for stubbing out properties that raise the PropertyChanged event. Now we will be able to bind this object to Silverlight input controls and the controls can cause the object values to be updated so that we can provide data validation from within our data object, rather than having to include validation logic in our user interface code. Data binding We are going to bind our CustomerInfo object to our data entry form, using Blend. Be sure to build the solution before switching back over to Blend. With MainPage.xaml open in Blend, select the LayoutRoot control. In the Properties panel enter DataContext in the search field and click the New button: In the dialog that opens, select the CustomerInfo class and click OK: Blend will set the DataContext of the LayoutRoot to an instance of a CustomerInfo class: Blend inserts a namespace to our class; set the Grid.DataContext in the XAML of MainPage.xaml: <Grid.DataContext> <local:CustomerInfo/></Grid.DataContext> Now we will bind the value of CustomerName to our customerName textbox. Select the customerName textbox and then on the Properties panel enter Text in the search field. Click on the Advanced property options icon, which will open a context menu for choosing an option: Click on the Data Binding option to open the Create Data Binding dialog: In the Create Data Binding dialog (on the Explicit Data Context tab), click the arrow next to the CustomerInfo entry in the Fields list and select CustomerName: At the bottom of the Create Data Binding dialog, click on the Show advanced properties arrow to expand the dialog and display additional binding options: Ensure that TwoWay is selected in the Binding direction option and that Update source when is set to Explicit. This creates a two-way binding, meaning that when the value of the Text property of the textbox changes the underlying property, bound to Text will also be updated. In our case the customerName property of the CustomerInfo class: Click OK to close the dialog; we can now see that Blend indicates that this property is bound by the yellow border around the property input field: Repeat this process for both the phoneNumber and emailAddress textbox controls, to bind the Text property to the PhoneNumber and Email properties of the CustomerInfo class. You will see that Blend has modified our XAML using the Binding Expression: <TextBox x_Name="customerName" Margin="94,8,8,0" Text="{BindingCustomerName, Mode=TwoWay, UpdateSourceTrigger=Explicit}"TextWrapping="Wrap" VerticalAlignment="Top" Grid.Column="1" Grid.Row="1" MaxLength="40"/> In the Binding Expression code the Binding is using the CustomerName property as the binding Path. The Path (Path=CustomerName) attribute can be omitted since the Binding class constructor accepts the path as an argument. The UpdateSourceTrigger is set to Explicit, which causes any changes in the underlying data object to force a re-bind of the control. For the eventDate control, enter SelectedDate into the Properties panel search field and following the same process of data binding, select the EventDate property of the CustomerInfo class. Remember to ensure that TwoWay/Explict binding is selected in the advanced options:
Read more
  • 0
  • 0
  • 1992

article-image-moodle-19-theme-design-customizing-header-and-footer-part-2
Packt
23 Apr 2010
6 min read
Save for later

Moodle 1.9 Theme Design: Customizing the Header and Footer (Part 2)

Packt
23 Apr 2010
6 min read
Customizing the footer Obviously, the second thing that we are going to do after we have made changes to our Moodle header file is to carry on and change the footer.html file. The following tasks will be slightly easier than changing the header logo and title text within our Moodle site, as there is much less code and subsequently much less to change. Removing the Moodle logo The first thing that we will notice about the footer in Moodle is that it has the Moodle logo on the front page of your Moodle site and a Home button on all other pages. In addition to this, there is the login info text that shows who is logged in and a link to log out. More often than not Moodle themers will want to remove the Moodle logo so that they can give their Moodle site its own branding. So let's get stuck in with the next exercise, but don't forget that this logo credits the Moodle community. Time for action – deleting the Moodle logo Navigate to your mytheme directory and right-click on the footer.html file and choose Open With | WordPad. Find the following two lines of code: echo $loggedinas;echo $homelink; Comment out the second line using a PHP comment: echo $loggedinas;/*echo $homelink; */ Save the footer.html file and refresh your browser window. You should now see the footer without the Moodle logo. What just happened? In this exercise, we learned which parts of the PHP code in the footer.html file control where the Moodle logo appears in the Moodle footer. We also learned how to comment out the PHP code that controls the rendering of the Moodle logo so that it does not appear. You could try to put the Moodle logo back if you want. Removing the login info text and link Now that we have removed the Moodle logo, which of course is completely up to you, you might also want to remove the login info link. This link is used exactly like the one in the top right-hand corner of your Moodle site, insofar as it acts as a place where you can log in and log out and provide details of who you logged in as. The only thing to consider here is that if you decide to remove the login info link from the header.html file and also remove it from the footer, you will have no easy way of logging in or out of Moodle. So it is always wise to leave it either in the header or the footer. You might also consider the advantages of having this here as some Moodle pages such as large courses are very long. So, once the user has scrolled way down the page, he/she has a place to log out if needed. The following task is very simple and will require you to go through similar steps as the"deleting the logo" exercise. The only difference is that you will comment out a different line of code. Time for action – deleting the login info text Navigate to your mytheme directory and right-click on the footer.html file and choose Open With | WordPad (or an editor of your choice). Find the following two lines of code: echo $loggedinas;echo $homelink; Comment out the first line by using a PHP comment as shown below: /* echo $loggedinas; */ echo $homelink; Save the footer.html file and refresh your browser window. You will see the footer without the Moodle logo or the login info link. What just happened? In this task, we learned about those parts of the PHP code in the footer.html that control whether the Moodle login info text appears in the Moodle footer similar to the Moodle logo in the previous exercise. We also learned how to comment out the code that controls the rendering of the login info text so that it does not appear. Have a go hero – adding your own copyright or footer text The next thing that we are going to do in this article is to add some custom footer text where the Moodle logo and the login info text were before we removed them. It's completely up to you what to add in the next exercises. If you would like to just add some text to the footer then please do. However, as part of the following tasks we are going to add some copyright text and format it using some very basic HTML. Time for action – adding your own footer text Navigate to your mytheme directory and right-click on the footer.html file and choose Open With | WordPad. At the very top of the file, paste the following text or choose your own footer text to include: My School © 2009/10 All rights reserved. Save the footer.html and refresh your browser. You will see that your footer text is at the bottom of the page on the right-hand side. However, this text is aligned to the left as all text in a browser would be. Open the footer.html file again (if it isn't open already) and wrap the following code around the footer text that you have just added: <div align="right">My School &copy; 2009/10 All rights reserved</div> Save your footer.html file and refresh your browser. You will see that the text is now aligned to the right. What just happened? We just added some very basic footer text to our footer.html file, saved it, and viewed it in our web browser. We have demonstrated here that it is very easy to add our own text to the footer.html file. We have also added some basic HTML formatting to move the text from the left to the right-hand side of the footer. There are other ways to do so, which involve the use of CSS. For instance, we could have given the <div> tag a CSS class and used a CSS selector to align the text to the right. Have a go hero – adding your own footer logo Now try to see if you can edit the footer.html and add the same logo as you have in the header.html in to the footer. Remember that you can put the logo code anywhere outside of a PHP code block. So try to copy the header logo code and paste it into the footer.html. Finally, based on what we have learned, try to align the logo to the right as we did with the footer text.
Read more
  • 0
  • 0
  • 3390
Modal Close icon
Modal Close icon