Programming and Web Development PHP How do I update root certificates in Apache/PHP/cURL environment Following is the instruction for dealing with the new ISIS’ SSL certificate authority (effective 4/21/2006), Geo Trust, in a UNIX or Windows environment using Apache/ PHP /cURL. The instruction can generally apply to any new SSL certificate authority. UNIX If your web application is getting an error with ISIS login, try the following: 1. Your PHP was probably compiled with cURL, i.e, —with-curl=/usr/local/curl-7.12.0. Our cURL is installed in /usr/local/curl-7.12.0, but yours can be any arbitary path. Find out what is it. 2. Your cURL came with the default CA bundle file, which contains root certificates for all the well known certificate authorities at the time cURL was installed. Our file is /usr/local/curl-7.12.0/share/curl/curl-ca-bundle.crt, which is the default location for the default compilation of cURL. If you compiled cURL with a custom location for this file, find out what is it and that’s the one you will update. 3. Looked for the new ISIS certificate authority from Geo Trust in /usr/local/curl-7.12.0/share/curl/curl-ca-bundle.crt. Basically all the following 3 lines should be in curl-ca-bundle.crt: Equifax Secure Global eBusiness CA-1 Validity Period: Mon Jun 21, 1999 to Sun Jun 21, 2020 ( GMT ) Certificate Fingerprint (MD5): 8F:5D:77:06:27:C4:98:3C:5B:93:78:E7:D7:7D:9B:CC If any of these lines are not in curl-ca-bundle.crt, you need to update your curl-ca-bundle.crt. 4a. If you don’t have any local certificates in curl-ca-bundle.crt, you can replace the entire curl-ca-bundle.crt. Save the old curl-ca-bundle.crt and get cacert.pem from http://curl.haxx.se/docs/caextract.html . Replace curl-ca-bundle.crt with cacert.pem. 4b. If you have some local certificates in curl-ca-bundle.crt, get cacert.pem from http://curl.haxx.se/docs/caextract.html and extract “Equifax Secure Global eBusiness CA” certificate from cacert.pem by extracting the lines between and including: Equifax Secure Global eBusiness CA and END CERTIFICATE Make a copy of the current curl-ca-bundle.crt and then append this piece of new certificate data to curl-ca-bundle.crt. 5. Restart your Apache server (the PHP module in Apache reads curl-ca-bundle.crt at startup). 6. Test login to ISIS . Windows cURL in Apache/ PHP on Windows doesn’t read a CA Bundle at startup and must be set by the application. On Windows adjust your CA Bundle file as above for UNIX . If you don’t have one already read this . What are the differences between addslashes(), mysql_escape_string() and mysql_real_escape_string() addslashes() escapes single quote (’), double quote ("), backslash (\) and NUL (\x00). mysql_escape_string() and mysql_real_escape_string() escapes the characters above plus: CR (\r), LF (\n) and EOF (\x1a). Apparently (according to the manual), MySQL wants these characters escaped too, but my experiment shows otherwise (i.e. MySQL doesn’t care if these characters are in a string). Suppose: $value = 'bar'; // 'ba' and then CR-LF and then 'r' print “insert into pairs values (‘foo’, ’” . addslashes($value) . “’)” gives: insert into pairs values ('foo', 'ba\r\nr') print “insert into pairs values (‘foo’, ’” . mysql_real_escape_string($value) . “’)” gives: insert into pairs values ('foo', 'bar') In this case, the execution result should be the same, but the statement itself is different. For other EOF , the execution result and statement are identical for both functions. mysql_real_escape_string() is available on PHP 4.3.0 or above. mysql_escape_string() is deprecated and you should use mysql_real_escape_string() instead, as it takes the current character set into account when escaping characters. addslashes() should be enough for single-byte strings. For multi-byte strings though, mysql_real_escape_string() does provide better security. See this article for details. PHP manual on: addslashes mysql_escape_string mysql_real_escape_string PHP and ODBC While looking for something else in the Moodle Forums, I found these links that refer to the underlying way Moodle connects to databases using ODBC . “adodb just harnesses the underlying PHP functions for whatever type of connection you use, so it helps to be familiar with how they work.” http://uk.php.net/odbc http://www.phpfreaks.com/tutorials/61/0.php http://phplens.com/phpeverywhere/node/view/9 http://bryanmills.net:8086/archives/2003/11/microsoft-access-database-using-linux-and-php/ (Links taken from this Moodle Forums post. http://moodle.org/mod/forum/discuss.php?d=74133 ) https://kb.ucla.edu/link/1088 Please add more, if you find any. Speed of unpack() in PHP I needed to extract a list of integers from a binary string. I was curious to know if PHP’s unpack function is fast compared to a custom function, so I wrote a test for it. ';$unpack_time = 0.0;$unpack_time2 = 0.0;$unpack_custom_time = 0.0;$fp = fopen($filename, 'rb');while (!feof($fp)) { $content = fread($fp, 1048576); $start = microtime(true); $array = unpack('N*', $content); $stop = microtime(true); $unpack_time += ($stop - $start); $start = microtime(true); $array = unpack('V*', $content); $stop = microtime(true); $unpack_time2 += ($stop - $start); $start = microtime(true); $array = unpack_custom($content); $stop = microtime(true); $unpack_custom_time += ($stop - $start);}fclose($fp);print "\$unpack_time = $unpack_time\n";print "\$unpack_time2 = $unpack_time2\n";print "\$unpack_custom_time = $unpack_custom_time\n";function unpack_custom($content) { $len = strlen($content); $result = array(); for ($i = 0; $i + 3 < $len; $i += 4) { $result[] = (ord($content[$i]) << 24) + (ord($content[$i + 1]) << 16) + (ord($content[$i + 2]) << 8) + ord($content[$i + 3]); } return $result;}?> The printout: (The numbers are the number of seconds needed to convert the file’s content into integers. The file I used was 2.67 MB in size.) $unpack_time = 1.34654474258$unpack_time2 = 1.44259476662$unpack_custom_time = 127.910765171 The result matches my earlier experiment, from which I have learned that custom functions are much slower than PHP’s built-in ones. Whenever possible, use the latter. By do that, you also have less code to write and debug. Configuring PEAR on Windows PEAR is the PHP Extension and Application Repository. Applications written in PHP often include references to external libraries and PEAR is a way to manage these. On Windows if PEAR hasn’t already been configured log in to the server and run go-pear.bat in the PHP directory (C:\php in this case). This adds the PEAR settings to php.ini: include_path=“.;C:\php\pear” It also creates “pear.bat” which can be used to search for and install components. For instance: pear search Requestpear install HTTP_Request If you use the Apache Web Server after running go-pear.bat it’s necessary to restart Apache (as with any other changes to php.ini). How do I use cURL in PHP on Windows? To configure cURL to be able to run in PHP uncomment this line (remove the semi-colon) in the php.ini file: ;extension=php_curl.dll Apparently in UNIX systems Apache will read cURL’s curl-ca-bundle.crt file at startup and cURL will be able to use that information. The regular Windows Apache version does not have a full cURL installation, merely the .dll (as referenced above). It will not read curl-ca-bundle.crt in the folder with php_curl.dll and it will also not read curl-ca-bundle.crt in Apache’s configuration folder. To get this functionality under Windows in your application you must set the CURLOPT_CAINFO option to point to the location of a Certificate Authority Bundle file like this: curl_setopt($ch, CURLOPT_CAINFO, ’C:/accessible/by/apache/cacert.pem); Once this is done you will be able to verify SSL certificates by setting the VERIFYPEER option to true (the default for later versions of cURL) like this: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); A good CA Bundle file can be found on this page . If you have problems you may need to update your CA Bundle file. In particular, the SSL Certificate for the Test ISIS Server cannot be read using curl-ca-bundle.crt from the latest full cURL version for Windows. Passing command-line arguments into PHP Say you have a PHP script and you want to pass command-line arguments into the script, e.g. calling the script like this: php script.php datafile.txt 10 100 PHP stores all command-line arguments in an array: $argv 0 => “script.php” $argv 1 => “datafile.txt” $argv 2 => 10 $argv 3 => 100 Then you can process the arguments: if (!isset($argv 1 ) { print “Usage: php script.php [ ]\n”; exit(1); } $filename = $argv 1 ; … See the article Using PHP from the command line for details. Using SSL socket in PHP under Windows Problem If you try to open a socket (fsockopen, pfsockopen) with SSL in PHP 4.x under Windows, the operation might fail with the following message: Warning: fsockopen(): no SSL support in this build This problem occurs even if phpinfo() shows openssl as loaded and the command php -m shows openssl as one of the loaded module. Cause To use SSL in sockets, PHP core must be compiled with OpenSSL, which is not the case with the binary available at php.net. On the other hand, the openssl module only enables the OpenSSL functions (functions prefixed openssl_). According to the bug report linked below, “OpenSSL support enabled” that phpinfo() states just means that the openssl extension is available. Solution This problem has been identified and labeled “won’t fix” in the offical PHP distribution ( details ). You have the following options: Upgrade to PHP 5.x, which does not have such problem. If you are using PHP 4.3.x, you can download a (unofficial) SSL -enabled php4ts.dll . Use PHP’s curl extension (which is supported by the Windows binary from php.net) instead. PHP Resources PHP is a web programming language that can be compiled into the Apache web server and with its persistent connections to MySQL it makes for a very popular and fast web programming environment. PHP Cheat Sheet https://websitesetup.org/php-cheat-sheet/ Documenting PHP phpDocumentator phpXref Joseph Vaughan’s favorite articles on PHP security http://www.linuxjournal.com/article.php?sid=6061 http://www.linuxjournal.com/article.php?sid=6559 Use @ to turn off warning error message on a given command MVC frameworks for PHP (things like Ruby-on-Rails) Laravel: https://laravel.com Cake: http://www.cakephp.org Symfony: http://www.symfony-project.com CodeIgniter: www.codeigniter.com Debian packages for bleeding-edge versions of PHP and other LAMP -related packages: http://www.dotdeb.org PHPunit – Unit Testing for PHP http://codepad.org/ – test snippets of code in PHP and many other languages. PHP error reporting Error levels name value description example 1 example 2 E_ERROR 1 Fatal run-time errors notdefined(); E_WARNING 2 Run-time warnings 1 / 0; E_PARSE 4 Compile-time parse errors +-; E_eval(‘+-;’); E_NOTICE 8 Run-time notices print $i_am_not_defined; E_CORE_* varies generated by PHP core E_USER_* varies generated by trigger_error E_ALL 2047 Everything Custom Error Handler It can only catch E_WARNING, E_PARSE, E_USER_ERROR, E_USER_WARNING and E_USER_NOTICE. If something else happens, PHP’s default error handler takes place. functional my_error_handler($errno, $error, $file, $line) { ... handle the error ...} set_error_handler(‘my_error_handler’); Apache In Apache, you can customize how it responses to a particular HTTP status code. It can show a message or load a specific page. e.g. (from Apache’s doc) ErrorDocument 500 /cgi-bin/crash-recoverErrorDocument 500 "Sorry, our script crashed. Oh dearErrorDocument 500 http://xxx/ ErrorDocument 404 /Lame_excuses/not_found.htmlErrorDocument 401 /Subscription/how_to_subscribe.html However, when executed as an Apache module PHP returns a HTTP status code of 200 (OK) even if there is an compile or run-time error. (Not sure if it’s a bug or a feature, since this behavior is not mentioned anywhere else.) Therefore, one cannot use Apache’s custom error capability for PHP errors. Instead, either use a custom error handler (see above) or have PHP wrap the message inside some specific HTML code (see below). Pretty-printing Error Messages Config keys error_prepend_string and error_append_string are used to determine the HTML code that prepends or appends an error message. e.g. To display each error message inside a box, put these in php.ini: ; String to output before an error message.error_prepend_string = "
An error has occured. Please notify the administrator with the following error message:
"; String to output after an error message.error_append_string = "
" To make the change effective to a directory instead of system-wide, put these in .htaccess: php_value error_prepend_string "(... starting tags ...)"php_value error_append_string "(... ending tags ...)" Note: Because any compile-time error stops the compilation, there will be at most one box. PHPXref vs PHPDocumentor Introduction There exists a wide array of PHP documentation tools on the web available free for download. Two of the most popular ones are PHPXref and PHPDocumentor. Here, I outline the differences between the two to help you decide which one you should use. The following information was taken from http://phpxref.sourceforge.net/ and http://www.phpdoc.org/ . Similarities The greatest similarity between the two tools is, of course, their ability to read PHP documents and output information about them in another format, namely HTML . Both of these documentors highlights elements of the source in order to increase readability. PHPXref has also adopted the PHPdoc commenting standard to give additional information about pages, while recent versions of PHPdocumentor has adopted PHPXref’s ability to cross reference source code. The Strengths of PHPXref PHPXref is programmed in Perl which is directly run by your machine. In that way, it is potentially faster than PHPdocumentor which does the processing through PHP itself. The HTML output of PHPXref is very neat – it implements a bit of javascript to provide neat rollover visuals on additional information. Perhaps the strongest feature of PHPXref is its ability to provide information even without PHPdoc comments. Very easy to use and set up. You simply drag the files you want information about in a source folder, run the command prompt, and grab the documentation from the source folder. Although I haven’t tested it, PHPXref mentions that they provide information about SQL tables. The Strengths of PHPDocumentor Provides both a web and a command line interface. Can output in CHM , HTML , and PDF !! The interface allows a lot more customization than PHPXref. It can generate the resultant documentation in your own web interface (or you can choose one of their pre-built ones) in addition to choosing the source directory and the output directory. This level of customization is really what makes PHPXref more difficult to use than PHPXref which decides those things for you. Has an active community with a well-detailed online documentation. #Can create class inheritance diagrams (Not tested) Their documentation IS the standard. Expect new features and updates. Bundled with Zend Studio, a popular web development software. Summary Perhaps the main reason to use PHPXref is its ability to provide information without PHPdoc comments. This ability gives PHPXref a speed advantage if you want quick documentation without having to go back and comment lines and lines of code (although you should consider getting around to it!). This type of development favors procedural programming to an extent. Personally, I like PHPdocumentor’s ability to create PDF’s and its online documentation. Another cool feature is perhaps the ability to infer class inheritance straight from the source code. The rest of the features of PHPdocumentor is just eye candy. Keep in mind that PHPdocumentor will have immediate support for PHPdoc style commenting. New versions of PHP may create a need for more commenting standards that PHPdocumentor will be quick to adopt. I suspect that in the future, PHPdocumentor will continue to adopt useful features from other documentation tools. But in reality, the major differences between PHPXref and PHPdocumentor have been neutralized – using either one will likely suffice for your needs. Create a PHP unit test case using SimpleTest You can download SimpleTest at https://sourceforge.net/projects/simpletest/ Suppose you have a PHP file called math.php that contains functions that you want to test. Then you can write a test case in another file, say mathtest.php . (Suppose you have downloaded and extracted SimpleTest to C:\simpletest .) UnitTestCase(); } function testSquare() { $this->assertEqual(16, square(4)); }}$test = &new TestOfLogging();$test->run(new TextReporter());?> (Each function named test* in this class represents a test case and will be run automatically by SimpleTest.) Run the test case with the command php mathtest.php . As the square function is written correctly, the test case will pass. testofloggingOKTest cases run: 1/1, Passes: 1, Failures: 0, Exceptions: 0 Try changing the square function and see what happens. PHP Commenting Style Any programmer can tell you that good commenting in your source code is an integral part of programming. Whether the language you’re dealing with is an interpreted language like Javascript or compiled like C++, good comments lead to better readability and better flow of logic. Developers of the Java programming language have come up with a strict commenting standard for Java to interface with a program called Javadoc. Not only does this standard remind the programmer to make appropriate comments, it also allows Javadoc to parse the strict comments into HTML documentation. The success of Javadoc carried over PHP with the creation of PHPDoc. The commenting syntax of PHPDoc is widely supported in the PHP community. Parsers for this standard include phpxref and phpdocumentor . Basic Syntax Here’s an example of PHPDoc style comments: /*** This is a short description** This is a longer description of the element that* I will comment. It can run over to as many lines* as necessary. Notice the asteriks at the beginning* of each commenting line.*/ All PHPDoc comments begin with /** on its own line at the top and ends with a */ at the bottom. Each line of commenting is denoted by the single asterik at the beginning of each line. By convetion, PHPDoc comments begin with a short description followed by a longer description. Let’s look at a more realistic example where we wish to comment on a dispenseIceCream() function: /*** Dispenses desired flavored ice cream** Called upon when user has entered their* favorite ice cream. The function checks* if the desired flavor is available in the* amount desired. If so, then it dispenses* the ice cream.** @access private* @param int $flavor Flavor of the desired ice cream* @param int $amount_desired Amount of ice cream user wants* @return $string Name of the flavor. Returns error string if not available*/private function dispenseIceCream($flavor,$amount_desired){ ...return $name_of_flavor;} I’ve thrown a lot of new things in the above code, but the syntax should be somewhat self-explanatory. First, you should have noticed the @ tags. Tags in PHPDoc tell the parser exactly what you are going to be describing in your comments. Notice that each tag has its own parameters, separated by a space as in the @param tag. Tags are, in essence, the strength of PHPDoc. @access tells the parser that the following element we are commenting on (the dispenseIceCream function) is a private function. @param gives the parser information about the parameters that the function takes in. Finally, @return provides information about what kind of output to expect out of the function. Each tag in PHPDoc has its own syntax. For more information, look at the documentation Useful Tags Using every single tag in PHPDoc leads to the issue of overcommenting and obscurity of the actual code! Here, I outline what I deem to be useful tags to place in your document (tag info from phpdocumentor ): @access (private | protected | public) The access tag will allow the documentation to clearly state how an element should be accessed. This is important for programming design purposes. @param datatype $paramname description I consider this tag to be one the most important tags in PHPDoc. It allows a quick look at how the input of a function should be formatted in order to use it. @return datatype description Similar to the @param tag, when dealing with functions, one of the things a programmer cares to look for is what this function will output. @uses (please refer to documentation for proper syntax) This tag allows actual linking and backlinking to another element! Its a neat feature that allows someone browsing the documentation to quickly see related functions or variables the element uses. The syntax is a bit tricky, so please study it. @var datatype description A nice tag to comment on important variables. Other Tags to Note The following tags might be useful or nice in your commenting and documentation, but I wouldn’t consider them to be the bread and butter of PHPDoc. @global datatype $globalvariablename | description Global variables should be given more attention to. This tag should be used with @var. @ignore For whatever reason, you may not want PHPDoc to parse the following element. the @ignore tag (with no parameters) does just that. You can go ahead and give it a description if you feel its necessary. @static Similar to @access, program design is one of the things programmers may want to reference in your code. The static tag whether a a certain class of method should be treated as static. @staticvar Same as @static, except for variables. inline {@link URL description} This in-line tag is very useful whenever you wish to reference something outside within your descriptions. It creates a link to the URL you specify within the documentation. There are other inline tags, but this one is the most versatile (but possibly not the easiest to use). phpMyAdmin Security phpMyAdmin Security Announcements PHP PHP eXtremePHP and http://pear.php.net/ These code bases will be useful in rolling the PHP out more quickly – Jose A higher level PHP web application framework is the Horde framework http://www.horde.org/ – Jose http://www.phpoki.org/ CakePHP Zend Symfony CodeIgniter PHP on Trax Seagull How can I make phpMyAdmin avoid sending MySQL passwords in the clear? Although phpMyAdmin is an excellent tool for administering MySQL databases, you don’t want to expose your MySQL usernames and passwords to sniffing over the wire by sending them “in the clear.” The solution, if you are running https, is to simple edit the config.inc.php file like this. The default is FALSE . $cfg[‘ForceSSL’] = TRUE ; // whether to force using https PHP ODBC Setup Guide Guide to setting up php-odbc for connection to Registrar database. Example for RedHat EL 5. Create file tds.datasource.template: [Registrar] Driver = FreeTDS Description = UCLA Registrar ( SRDB ) Trace = No Server = srdb.registrar.ucla.edu Port = 1433 Create file tds.datasource.template: [FreeTDS] Description = v0.63 with protocol v8.0 Driver = /usr/lib/libtdsodbc.so Make sure Driver points to an existing file. Run the following command: sudo yum install php-odbc sudo odbcinst -i -d -f tds.driver.template odbcinst -i -s -f tds.datasource.template sudo cp ~/.odbc.ini /etc/odbc.ini Test the connection: Note on programming: do not nest odbc_exec() calls! Make one call, copy records into array, odbc_free_result() it, and then move on. Second odbc_exec() will fail otherwise. More info on settings at http://www.unixodbc.org/doc/FreeTDS.html Performance of array_shift and array_pop in PHP We have confirmed that array_shift is much slower than array_pop in PHP . Code: Result: array_pop takes 0.00089 seconds array_shift takes 15.15544 seconds array_reverse + array_pop takes 0.03934 seconds JavaScript Javascript Javascript, also known as ECMAscript, is used to make web browsers perform certain actions before returning to the web server. It depends on web browsers behaving the same. This was problematic for a long time, but is getting much better. Here are a few Javascript resources. http://www.javascript.com/ JavaScript Puzzlers: A 37 Question JavaScript Quiz JavaScript Tools of the Trade: JSBin JavaScript: The World’s Most Misunderstood Programming Language – Douglas Crockford © 2001 His more recent book JavaScript: The Good Parts – Douglas Crockford © 2008 The Young Developer’s Guide to Debugging JavaScript By ANDRE BEHRENS – N.Y. Times JavaScript Language Resources JavaScript Weekly – A free, once–weekly e-mail round-up of JavaScript news and articles. Select All_ JavaScript for Forms Posting to an Array WYSIWYG Editors written in Javascript http://jquery.com/ Frequently Misunderstood JavaScript Concepts by Michael Bolin, October 28, 2013 Learn to play Javascript by playing this game – Code Combat (new) Speaking Javascript by Dr. Axel Rauschmayer – free HTML version – March 2014 (new) You Don’t Know JS book series – free online, or you can buy them – Feb. 2015 It is simultaneously a simple, easy-to-use language that has broad appeal, and a complex and nuanced collection of language mechanics which without careful study will elude true understanding even for the most seasoned of JavaScript developers. UCLA KB Articles tagged with Javascript Numeric Validation JavaScript Series I : Validation ( AJAX Presentation CWP ) Several people have asked me to discuss some of the details from the AJAX presentation from our last Campus Web Publishers ( CWP ) meeting. In this article, which is part of the AJAX presentation series, I will share some validation functions I have used to validate the grid. In addition to validating the field, notice how it maps the arrows keys to give the user a Microsoft Excel like feel. Validating a numeric field function NumbersOnly(Object) { if(CurrentCellClicked) { if((event.shiftKey && event.keyCode == 9) || event.keyCode==37) { event.returnValue=true; return ; } else if(event.keyCode==9 || event.keyCode==39) { event.returnValue=true; return ; } } if(event.keyCode == 36 || event.keyCode == 35 || event.keyCode == 46 || event.keyCode == 8) event.returnValue=true; else if((event.shiftKey && event.keyCode == 9) || event.keyCode==37) { var t = parseInt(Object.nextField); if(t > 2) { t = GlobalForm['c'+(t-2)]; if(t.disabled) { GlobalForm['c'+(t.nextField-2)].select(); GlobalForm['c'+(t.nextField-2)].focus(); } else { t.select(); t.focus(); } event.returnValue = false; } } else if(event.shiftKey) event.returnValue = false; else if(event.keyCode==9 || event.keyCode==39) { var t = GlobalForm['c'+Object.nextField]; if(t.disabled) { GlobalForm['c'+t.nextField].select(); GlobalForm['c'+t.nextField].focus(); } else { t.select(); t.focus(); } event.returnValue = false; } else { event.returnValue = ((event.keyCode >= 48 && event.keyCode <= 57) || (event.keyCode>=96 && event.keyCode<=105)); }} Validating a currency field function CurrencyOnly(Object) { if(CurrentCellClicked) { if((event.shiftKey && event.keyCode == 9) || event.keyCode==37) { event.returnValue=true; return ; } else if(event.keyCode9 || event.keyCode39) { event.returnValue=true; return ; } } if(event.keyCode == 36 || event.keyCode == 35 || event.keyCode == 46 || event.keyCode == 8) event.returnValue=true; else if((event.shiftKey && event.keyCode == 9) || event.keyCode37) { var t = parseInt(Object.nextField); if(t > 2) { t = GlobalForm['c'+(t-2)]; if(t.disabled) { GlobalForm['c'+(t.nextField-2)].select(); GlobalForm['c'+(t.nextField-2)].focus(); } else { t.select(); t.focus(); } event.returnValue = false; } } else if(event.shiftKey) event.returnValue = false; else if(event.keyCode9 || event.keyCode==39) { var t = GlobalForm[’c’+Object.nextField]; if(t.disabled) { GlobalForm[’c’+t.nextField].select(); GlobalForm[’c’+t.nextField].focus(); } else { t.select(); t.focus(); } event.returnValue = false; } else { event.returnValue = (event.keyCode == 110 || event.keyCode == 190 || event.keyCode == 109 || event.keyCode == 189 || (event.keyCode != 47 && ((event.keyCode>=45 && event.keyCode<=57) || (event.keyCode>=96 && event.keyCode<=105)))); } } Validating a Date Field function DateOnly(Object) { if(CurrentCellClicked) { if((event.shiftKey && event.keyCode == 9) || event.keyCode==37) { event.returnValue=true; return ; } else if(event.keyCode9 || event.keyCode39) { event.returnValue=true; return ; } } if(event.keyCode == 36 || event.keyCode == 35 || event.keyCode == 46 || event.keyCode == 8) event.returnValue=true; else if((event.shiftKey && event.keyCode == 9) || event.keyCode37) { var t = parseInt(Object.nextField); if(t > 2) { t = GlobalForm['c'+(t-2)]; if(t.disabled) { GlobalForm['c'+(t.nextField-2)].select(); GlobalForm['c'+(t.nextField-2)].focus(); } else { t.select(); t.focus(); } event.returnValue = false; } } else if(event.keyCode9 || event.keyCode==39) { var t = GlobalForm[’c’+Object.nextField]; if(t.disabled) { GlobalForm[’c’+t.nextField].select(); GlobalForm[’c’+t.nextField].focus(); } else { t.select(); t.focus(); } event.returnValue = false; } else { event.returnValue = (event.keyCode == 109 || event.keyCode == 189 || event.keyCode == 191 || event.keyCode == 111 || (event.keyCode>=47 && event.keyCode<=57) || (event.keyCode>=96 && event.keyCode<=105)); } } Of course, date validation also requires: function IsDate(DateObject) { var month, year, day; if(DateObject.value.length < 6) { var datePat = /^(\d{1,2})(\/|-)(\d{1,2})$/; var matchArray = DateObject.value.match(datePat); // is the format ok? if (matchArray == null) return false; month = matchArray 1 ; // parse date into variables day = matchArray 3 ; year = (new Date()).getFullYear(); } else { var datePat = /^(\d{1,2})(\/|-)(\d{1,2})(\/|-)(\d{2,4})$/; var matchArray = DateObject.value.match(datePat); // is the format ok? if (matchArray == null) return false; month = matchArray 1 ; // parse date into variables day = matchArray 3 ; year = matchArray 5 ; } if (month < 1 || month > 12) { // check month range throw (new Exception(“Month must be between 1 and 12.”)); } if (day < 1 || day > 31) { throw (new Exception(“Day must be between 1 and 31.”)); } if ((month4 || month6 || month9 || month11) && day==31) { throw (new Exception("Month “ month ” doesn’t have 31 days")); } if (month == 2) { // check for february 29th var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)); if (day > 29 || (day==29 && !isleap)) { throw (new Exception("February " + year + " doesn’t have " + day + " days!")); } } if(year.toString().length>2) { year = year = year.toString().substring(2); } DateObject.value = (parseInt(month)) + ‘/’ + (parseInt(day)) + ‘/’ + year; return true; // date is valid } The advantages of Javascript Introduction Javascript is a browser-interpreted language that was created to access all elements of HTML and the browser. The processing is done entirely by the client-side browser which makes it very useful tool to handle processing which would have otherwise been checked server-side, thereby reducing overhead. Javascript is also used to increase user interaction, animate objects, create drop down navigation, grab data from databases, and more! If you are working with webpages in any way, javascript will help. In this article, I attempt to point out the advantages in learning this powerful language. Making Magic with DHTML You have probably encountered javascript through your years of web surfing without knowing it. Currently, the most popular implementation of javascript is the rollover. You know, when your cursor “rolls over” an image and it changes. Another popular use of javascript is drop down navigation menus. Javascript is used to create “magic” effects on webpages in conjunction with CSS (Cascading Style Sheets). The combination of HTML , CSS , and javascript is called DHTML for Dynamic HyperText Markup Language. The Dynamic in DHTML refers to how elements in the webpage appear to move or change, usually by user interaction. Not surprisingly, the brains behind these effects is javascript. HTML was designed for web authors to quickly and easily create web pages. With only knowledge of HTML , designers will not have access to certain areas of the web browser. Examples include the status bar, browser information, browser window size, cookies, and browser history. Javascript is needed in those cases in order to access those elements and do things with them. CSS can give properties to HTML elements that can’t be created through tags. CSS is also used in conjunction with Javascript in order to identify and categorize certain HTML elements. By systemitizing these elements, javascript can then access them much more easily. If you are designing a website for public access, implementing some DHTML helps your audience and navigate interact with your pages. Dynamic Data with AJAX The “Dynamic” in DHTML is a bit of a misnomer in the sense that the content does not change. In some effects, the content is simply hidden from the audience and revealed later with javascript. True dynamic content would require some sort of access to external data such as a text file or a database. Unfortunately, since javascript was designed as a client-side tool, it is not the ideal way to fetch data for you. However, with a bit of clever programming, developers have come up with a solution that integrates javascript, XML , and PHP together. This technology is called AJAX – Asynchronous Javascript And XML . The basic idea of AJAX is to use the event handlers of javascript to fetch external data from an external PHP / ASP page. This page, in turn, fetches the data from the database and generates an XML file with the content. The javascript parses the xml file and embeds the data straight into the HTML . While the backend programming may seem a bit complicated, the advantages of AJAX benefit both server and client sides. Traditionally, dynamic data can only be generated by a page refresh. Not only does this interrupt the flow of your web applications, the server must also resend the entire webpage, resulting in unnecessary overhead. One of the major benefits of AJAX is that your web applications do not need to be refreshed . To the client, a simple button click generates dynamic data straight on the screen seemlessly . To the server, only the data that is requested by the client is sent. Furthermore, since the raw data is being parsed and processed through javascript, AJAX saves the server precious processing cycles. The result: dynamic, seamless webpages that are optimized for speed. Javascript Form Validation As I’ve hinted in the introduction, javascript can be used to validate HTML form fields. Let’s imagine a familiar scenario in which a server is at maximum and webpages are being served slowly. Imagine a innocuous client who forgets to type in the “at” on the email field of a form. He clicks submit and waits … and waits and … waits only to receive a cold “invalid input” message. Then he clicks the back button on the browser, which asks if he wants to retrieve the webpage again. The user has no choice but to say yes, and he waits…and waits.. and waits only to go back to the original screen and try again. Not only does all this waiting frustrate the client, the server was also bothered by having to do the check on the email field. Javascript can act as the intermediary between the submitted form and server. In our imaginary example above, javascript steps in and immediately tells the client that he forgot the “at”. Only when the form is valid does the page go to bother the already-busy server. Javascript is a completely object-oriented language. While the “script” in javascript may imply on-the-fly procedural programming, it has capabilities to create objects, methods, and even inheritance! This, along with dynamic data fetching through AJAX , allows you to truly create complex and powerful applications. Conclusion To learn more about javascript and all the aforementioned technologies, I highly recommend http://www.w3schools.com/ both as a tutorial and a reference. Be sure to read up on the DOM model to take advantage of the power of this language. In the center of all of these web technologies is javascript. The language itself is simple in that you don’t need to worry about data types, compilers, or forgetting that semicolon! Javascript is also powerful in how integral it is to so many existing technologies. It saves server frustration, client frustration, and programmer frustration. The next time you create a web page, think about how might it be improved with javascript. jQuery Tutorial Learn the basic building blocks of jQuery in a two hour combination of videos, and interactive console challenges. – http://try.jquery.com/ Please list any other useful jQuery Tutorials you know of. Which Javascript framework should I use? So you’re tasked with creating a new web site or enhancing an old one and you need to provide some nice UI components or a RIA , the question is, what to use? We have faced this question at the Digital Libraries, and found the best approach for us is to define the requirements and audience of the application. Usually, when asking around about js frameworks, the default answer is often jquery and in most cases jquery is a very good choice, but it also depends on what type of application you are building. If you are interested in mimicking a desktop application feel, Ext-js might be a library to take a look at, which is a javascript library of almost Windows-like control widgets. An example of this might if your site has an admin portion, and needs very fine grained control such as trees, file and directory browsers, editable data grids, etc… A nice comparison of several js frameworks is available here: http://fictionalrealm.com/coding/2009/04/19/javascript-ui-framework-comparison-or-why-i-choose-extjs-jquery/ If you are looking to build an app-like web project for mobile and tablet devices, the Sencha Touch library looks to fit that niche. Sencha Touch jQuery and JavaScript Coding: Examples and Best Practices When used correctly, jQuery can help you make your website more interactive, interesting and exciting. This article will share some best practices and examples for using the popular Javascript framework to create unobtrusive, accessible DOM scripting effects. The article will explore what constitutes best practices with regard to Javascript and, furthermore, why jQuery is a good choice of a framework to implement best practices. http://www.smashingmagazine.com/2008/09/16/jquery-examples-and-best-practices/ Java Java Java is an object-oriented programming language that is intended to be runnable from many different operating systems without recompiling. Essential Links Home Page: http://java.sun.com Downloads: http://java.sun.com/downloads/ Forums: http://forum.java.sun.com/index.jspa Tutorials: http://java.sun.com/learning/tutorial/ Community: http://www.theserverside.com Conference: http://java.sun.com/javaone/sf/ Open Source The Apache Software Foundation: http://www.apache.org/ O’Reilly Open Source Java Directory: http://www.onjava.com/pub/q/java_os_directory Java-Source.Net: http://java-source.net/ Books For Learning Java: Core Java, Volume I: Fundamentals by Gary Cornell, Cay S. Horstmann, Cay S. Forstmann Core Java, Volume II: Advanced Features by Cay Horstmann, Gary Cornell For Reference: The Java™ Programming Language by Ken Arnold, James Gosling, David Holmes The Java™ Language Specification by James Gosling, Bill Joy, Guy Steele, Gilad Bracha For Best Coding Practices: Effective Java by Joshua Bloch _ For Designing GUIs:_ Java Look and Feel Design Guidelines: http://java.sun.com/products/jlf/index.html Tools IDEs Eclipse: http://www.eclipse.org NetBeans: http://www.netbeans.org/ Sun Java Studio Enterprise: http://developers.sun.com/prodtech/javatools/jsenterprise/index.jsp Sun Java Studio Creator: http://developers.sun.com/prodtech/javatools/jscreator/index.jsp Frameworks Java Server Faces: http://java.sun.com/javaee/javaserverfaces/ Shale: http://struts.apache.org/struts-shale/ Spring: http://www.springframework.org/ Struts: http://struts.apache.org/ Webwork: http://www.opensymphony.com/webwork/ Tapestry: http://jakarta.apache.org/tapestry/ Grails: http://grails.codehaus.org/ RIFE : http://rifers.org/ Trails: https://trails.dev.java.net/ Hibernate: http://www.hibernate.org/ AJAX Prototype: http://prototype.conio.net/ Script.aculo.us: http://script.aculo.us/ Dojo: http://dojotoolkit.org/ DWR : http://getahead.ltd.uk/dwr/ Google Web Toolkit: http://code.google.com/webtoolkit/overview.html Java Server Faces: http://java.sun.com/javaee/javaserverfaces/ajax/tutorial.jsp Build Ant: http://ant.apache.org/ Maven: http://maven.apache.org/ Web Container Tomcat: http://jakarta.apache.org/tomcat/index.html Application Server JBoss: http://www.jboss.com/products/jbossas Geronimo: http://geronimo.apache.org/ Portal Liferay: http://www.liferay.com/web/guest/home JBoss: http://labs.jboss.com/portal/jbossportal/index.html Enterprise Content Management Alfresco: http://www.alfresco.com/ XML and Java XML and Java Cocoon is a Java-based framework. It utilized pipelines and SAX events to create a verstile XML parsing architecture. The Cocoon web site is at: http://cocoon.apache.org/2.0/ . Books are now coming out on Cocoon (check out Amazon). The O’Reilly web site has on-line articles on Cocoon: “Introducing Cocoon 2.0” ( http://www.xml.com/pub/a/2002/02/13/cocoon2.html ) , “Creating SOAP Services with Cocoon” ( http://www.xml.com/pub/a/ws/2003/03/18/cocoon.html ) —Jose Converting Java content into AJAX (Javascript and XML) If you have a program in Java or know how to program in Java and would like to convert your code to be used on websites as AJAX (Javascript and XML ), Google Web Toolkit can help do it for you instead of doing so by hand. Google Web Toolkit The Web Toolkit offers alot of tools for creating webcontent from your Java apps and is perfect for me since I dont have any experience with Javascript or XML . If you know how to program in Java, make sure to check it out. Create a Java class that is only comparable to itself In Java 5 and above, how to create a Java class that is only comparable to itself? The answer is to extend Comparable. This works even if TheClass uses generics. public class SelfComparableOnly implements Comparable> { ... public int compareTo(SelfComparableOnly o) { // Compare itself to o } ...} Removing old Java versions Java is notorious for installing updates (current version as of this writing is version 6, Update 23) but not removing the old versions. Finding a system with multiple Java versions (e.g. Java 6 Update 10, Java 6 Update 17, and Java 6 Update 20 all on the system’s Add/Remove Programs) is fairly common. Java until recently did not provide for proper “upgrading” of old versions or cleanup of them. Fortunately Java 6 Update 23 does do this properly. To remove older versions: http://www.java.com/en/download/faq/remove_olderversions.xml http://www.java.com/en/download/help/uninstall_java.xml It is, unfortunately, fairly primitive— simply to to Add/Remove Programs or Programs and Features and remove them one at a time by uninstalling them. Java Server Faces Java Server Faces ( JSF ) Mark Norton came across a very handy web page which documents all of the standard JSF tags and includes examples in XML and graphics. http://www.horstmann.com/corejsf/jsf-tags.html SQL MySQL Resources MySQL is a free, open-source relational database that has been used in thousands of websites, large and small. This is a contributed collection of resource links on MySQL. Feel free to add your favorites. Mike Franks – SSC Collection of Mysql links and articles http://www.sscnet.ucla.edu/mysql/ Notes while learning Mysql http://www.sscnet.ucla.edu/mysql/notes.htm Article on GRANTing access http://www.devshed.com/Server_Side/MySQL/Access/print_html Article I don’t understand on storing hierarchical data in a relational database. //would this work with Mysql?\\ http://www.oreillynet.com/pub/a/network/2002/11/27/bioconf.html Quick Tips to Optimize MySQL 8 Reasons Not to Use MySQL 5 Reasons To Use MySQL Ian Roessle November 9, 2002 at 13:23: phpMyAdmin is a very useful tool for managing Mysql databases from the web. And this article tells how to Turn on phpMyAdmin’s hidden features Client-side database tools Aqua Data Studio is a database query and administration tool that allows developers to easily create, edit, and execute SQL scripts, as well as browse and visually modify database structures. My favorite features: auto-completing SQL editor, and Excel-like editing of SELECT resultsets – the software generates automatically the appropriate UPDATE commands. Written in Java and supported on Windows, OS X, Solaris and Linux. Comes with JDBC drivers for MySQL, MS SQL Server 7/2000, Oracle 8/9/10, PostgreSQL and Sybase, and you can add drivers for other DBs. Runs fast. Free for educational use. DBDesigner4 is a visual database design system that integrates database design, modeling, creation and maintenance into a single, seamless environment. I use it to visually layout and plan my database schemas. Free. Only on Windows and Linux Point-and-Click MySQL Adminstration – Linux Magazine – Feb. 1, 2007 The MySQL Query Browser – Linux Magazine April 19, 2007 Server-side Admin Performance Tuning Best Practices for MySQL – Google Tech Talks – 43 min – Apr 28, 2006 Recommended by Harry Mangalam, UCI on UC- CSC Mailing List “This is a bit dated, but since so many web services use MySQL, this may still be useful.. It’s 43 min long, but the guy has a lot of useful hints and if you let it run in the background, you’ll pick up some things that will help, especially if you’re confused about the diffs between myisam and innodb tables and how to tune each.” Quick and Dirty MySQL Performance Troubleshooting – Jeremy Zawodny, Monday, August 17th, 2009 Linux Magazine General documentation and training MySQL University provides free download of talks on various topics. Be productive with the MySQL Command Line Fun with the MySQL pager command This article was originally posted on the UCLA Programmers Wiki. PostgreSQL Resources See Also: Who uses PostgreSQL at UCLA ? PostgreSQL official website: http://www.postgresql.org Modified versions: Bizgres ExtenDB Tuning Guides: PostgreSQL 8.0 Performance Checklist How the Planner Uses Statistics Server configuration options Graphical Admin Tools: pgAdmin Aqua Data Studio EMS SQL Manager for PostgreSQL Web-based Admin Tools: phpPgAdmin Why doesn't mysqlshow work for databases or tables with underscores in their names? mysqlshow has a tricky feature that interprets SQL wildcard characters (*,?,%,_) as wildcards if they appear in the last argument you give it. While the first 3 characters don’t get used much (if at all) in naming databases, the underscore is a common word separator and could cause problems if you try to use mysqlshow. Instead of showing the details of a database or table, if the object of interest has an underscore in its name, mysqlshow will treat it as a search and display only the name of the one object it finds. The trick to getting mysqlshow to display details is to add another argument at the end. mysqlshow only interprets wildcards in its last argument, so adding another one will tell the command to interpret the underscores literally and not as expressions for a search. To get the database underscores_are_great to show its tables, type: mysqlshow underscores_are_great % The ‘%’ on the end is a wildcard which will show all tables, which is what you want it to do. This works for displaying individual tables too, just add a ‘%’ as a final argument. See what else mysqlshow is good for What is mysqlshow good for? mysqlshow is a command-line tool included with standard MySQL distributions, similar to mysqladmin or other tools. mysqlshow is used to show summary information about databases and tables. Here is its basic usage: mysqlshow [OPTIONS] [database [table [field]]] There are four basic modes: No database given – all databases on the server are shown Database given only – all tables in that database are shown Database and table given – all fields in the given table of the database are shown Database, table, field given – only that field of the table is shown There is also a search mode, which is activated if the last argument contains an SQL wildcard (*,?,%,_). In this mode, all objects at the level of the last argument are searched. For example, mysqlshow ucla c% matches all tables in ucla starting with the letter ‘c’. Numerous options are available: -i shows extra information on the table view mode (when you specify only the database name), such as the storage engine, number of rows, creation and modification date. -v gives more info in all modes. In database listing mode, it shows the number of tables in each database. In table listing mode, it lists the number of columns. This option can be invoked multiple times for even more info! Many more (do mysqlshow —help) for a complete list for your version. Gotchas: mysqlshow may not behave as you want if your database or table name has an underscore in it. See the fix here . Also see the mysqlshow entry in the MySQL manual. How can I search/replace strings in MySQL? MySQL lets you replace all occurrences of a character or string of characters in a table with some other character or string. UPDATE table SET field1 = REPLACE(field1, 'replace_that', 'with_this'), field2 = REPLACE(field2, 'and_that', 'with_this') As an example, let’s say that you have a pets table and you want to change every cat into a dog: UPDATE pets SET species = REPLACE(species, 'cat', 'dog') This feature is also useful for transposing characters from one encoding to another. Here’s how to change Windows-style CRLF line endings into Unix-style LF line endings: UPDATE users SET bio = REPLACE(bio, CONCAT(CHAR(13), CHAR(10)), CHAR(10)) Of course, you don’t have to replace all occurrences in a table if you don’t want to. Just supply a WHERE clause and only those rows will be affected. Microsoft Access, OpenOffice and MySQL Using ODBC it is possible to connect Microsoft Access (or OpenOffice) to a MySQL database. Access or OpenOffice can even be used as “front end” to MySQL. The “MySQL Connector/ OBDC ” drivers are available at: < http://dev.mysql.com/doc/refman/5.0/en/connector-odbc.html> Installation information and documentation is available for Windows, Mac OS X and Unix platforms. WindowsXP: http://dev.mysql.com/doc/refman/5.0/en/connector-odbc-installation-binary-windows.html MacOS X: http://dev.mysql.com/doc/refman/5.0/en/connector-odbc-installation-binary-macosx.html SQL joins Please add other helpful links: SQL joins: a visual explanation http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html Get rid of default annoyances in MySQL Workbench By default, if you make any changes to table rows, there is an annoying 2-step confirmation dialog when you click Apply. It also prevents you from doing many mass UPDATEs and DELETEs (this is called ‘Safe Updates’). Safe Updates is a good idea in principle, since it stops you from running a DELETE without a WHERE clause, for example. But at the same time it prevents you from running an UPDATE / DELETE with a WHERE based on a column other than an ID, which I find myself doing sometimes. The confirmation dialog seems utterly pointless. You already have to click the ‘Apply’ button in the lower right corner to get your query to run, anyway. To turn off these options: In the menu, go to Edit > Preferences… Click on the ‘ SQL Queries’ tab In the ‘General’ section, uncheck ‘Safe Updates’ In the ‘Query Results’ section, uncheck ‘Confirm Data Changes’ These instructions are for version 5.2.47. Who uses PostgreSQL at UCLA? The purpose of this page is to create a directory of people who are using PostgreSQL and what advanced features they are using. Please try to mention how you have found certain features useful so that you can give other people ideas on how to better utilize the database. Jason Fong Database’s purpose: collecting large sets of data, and querying data (usually big long queries) to discover trends or other interesting results Total database size: approximately 500 GB Largest table: approximately 500 million rows Advanced features in use: Procedural languages: PL/pgSQL PL/perl: This is very useful— it lets one run bits of Perl code inside of a query. This can also be used to create a Perl function index on a table so that the Perl code doesn’t even need to be run for future queries. Triggers: I use these for a number of things: Automated auditing: a table can have a trigger that inserts a row into a log table whenever any insert/update/delete occurs Duplicate row detection: A table can have a trigger on inserts that checks for a duplicate primary key and then compares the other column values to the matching row. If all the columns are the same, the insert can be dropped. If any column is different, then the rows can be merged (or the new row could be inserted into a seperate table to keep track of these duplicate primary keys with different column values). Why NoSQL Matters Useful survey of NoSQL (and SQL ) technologies and a summary of the philosophy… http://blog.heroku.com/archives/2010/7/20/nosql Taken from email by Jose Hales-Garcia to Campus Web Publishers List Git and Version Control Subversion What is Subversion? Subversion is a version control system or SCM (software configuration management) tool. It is open-source and provides a feature set superior to that of CVS and Visual Source Safe. More information can be found at subversion.tigris.org . Tools for use with Subversion General tools The most popular and well-maintained Windows Subversion tool is TortoiseSVN . Tortoise is a Windows shell extension that integrates Subversion commands into Windows Explorer. NaughtySVN is a shell extension for the Gnome project’s Nautilus file manager. SCPlugin is a shell extension for Mac OSX , but as of this writing it is not up to date. RapidSVN is a cross-platform standalone Subversion GUI . SvnX is an OSX based tool similar to RapidSVN. ZigVersion – standalone client like svnX but some think it’s quite a bit easier to use. Subversion itself is cross-platform and features a very well-documented command line interface. IDE integration Subclipse is a Subversion plugin for Eclipse. AnkhSVN is a plugin for Microsoft Visual Studio, but it is no longer in active development. TortoiseSVN is the recommended tool for Windows/Microsoft developers. Apple has some information for using Subversion with XCode The Subversion Book / Documentation The entire O’Reilly book on Subversion is freely available online. Bernie Zimmerman has written a very simple tutorial about Installing Subversion on Fedora Core 3 Software Carpentry – Version Control with Subversion – Screencast How To Video https://kb.ucla.edu/link/514 Installing Subversion on Windows Subversion Best Practices Making the Most of Commit Hooks with Subversion – Linux Magazine, Oct. 9, 2008 – Registration Required Revision Control What is Revision Control? Revision control (also called version control or source control) is a method of tracking changes between various versions of a digital document. This is typically used for software code, but can be used for any type of digital document. For example, this knowlege base article tracks changes between versions, as do Wiki sites. Revision control for software is a vital part of Software Configuration Management or SCM . Bug tracking can also be considered a part of SCM . Why should I (a programmer) use Revision Control? The basic reasons are: Allows undoing and tracking of changes Makes it much easier to manage release and development versions of software Greatly facilitates more than one person working on a piece of software Promotes good programming practices If you’re not convinced, read this article: Why do You Need A Version Control System? . There is no reason not to be using Source Control, even if you are a single developer. Links / Documents Wikipedia’s entry on Revision Control is a good introduction to the concept and has a very useful glossary. Eric Sink has written an excellent and in-depth series of articles on source control . The articles focus on general version control concepts rather than specific tools. CVS Best Practices apply to CVS as well as other Revision control systems. This knowledge base article features an article listing and comparing some popular revision control systems. Revision Control Systems Compared Comparison charts There is an in-depth Version Control Systems Comparison available that covers many important features you might be looking for. Popular Systems and their Pros/Cons This list is by no means complete. For more in-depth information, refer to the link above. Visual SourceSafe SourceSafe is Microsoft’s own source control tool. If you do all of your development in Visual Studio, this is the easiest (but not necessarily best) tool for you. Pros: Excellent integration with Microsoft Visual Studio (Ease of Deployment) Many microsoft developers already have access to it Relatively easy to use Cons: Too simple for many users Commits are not atomic No support for changesets Not portable Proprietary and non-free CVS CVS is a very widely-used system. You should only use CVS if your environment has limitations that keep you from using SubVersion. Pros: Portable Excellent tool support Open-source / free More features than SourceSafe Cons: Dated – lacking many modern features No atomic commits Subversion Subversion is a newer open-source tool designed to replace CVS . It is superior to CVS in almost every way and is the best all-around open-source tool of its kind. There is an article in this knowledge base with more information about Subversion. Pros: All the pros of CVS plus Atomic commits High performance Vast array of configuration options Handles binary files efficiently as well Cons: Can be complex to setup depending on the configuration chosen No good Visual Studio integration yet Perforce Perforce is an easy to deploy and very feature-packed proprietary solution. It is used by Google. A free version is available, but it only supports a maximum of 2 users. Pros: Excellent feature-set Atomic commits Very good IDE integration (including Visual Studio) High performance Handles binary files efficiently as well Cons: Expensive Others One of the tools listed above will most likely be right for you, but they are not the only tools out there. There is no single best choice for a source control system. It is important to use the tool that is best for you. BitKeeper was used to manage the Linux kernel, Git (designed and developed by Linus Torvalds) is currently used to manage the Linux kernel, and ClearCase by Rational is also popular in many large companies. Distributed Version Control Systems http://en.wikipedia.org/wiki/Distributed_Version_Control_System Why distributed version control Choosing a Distributed Version Control System Thanks to Jose Hales-Garcia for his post on this on OSXForum . Future Expansion Someone with more information about Visual Studio Team System should add something about that. Installing Subversion on Windows Download and install the Windows binary . Download and install svnservice . Because we will run Subversion as a service, C:\Program Files\Subversion\bin must be part of the PATH environment variable. The installation should have done this but double-check this. Create a repository: svnadmin create “C:\IT\Subversion Repository” Make sure file permissions on this folder are locked down. Edit the conf/svnserver.conf file: [general] anon-access = read auth-access = write password-db = passwd [users] ${username1} = ${password1} ${username2} = ${password2} ${username3} = ${password3} Run SVNService Administration and fill in location of Subversion bin folder and the repository you created above. Notice the port (3690). Listen Host: should be set to the FQDN of the server so that it can be accessed remotely. Start the service. Change firewall settings to allow connections to this port as desired. Install Tortoise SVN on a client computer. Create a project with the usual subfolders: branches tags trunk External Links http://blogs.vertigosoftware.com/teamsystem/archive/2006/01/16/Setting_up_a_Subversion_Server_under_Windows.aspx http://www.stanford.edu/~bsuter/subversion-setup-guide/ GIT info Please add other helpful links: http://www.git-tower.com/blog/git-cheat-sheet-detail/ Interactive tutorial about branching – (Learning about git branching) Mostly for beginners – (List of Git Tutorials from 2011) Role specific command references for different types of git users- (Everyday git commands from kernel.org) 10 Tips to Push Your Git Skills to the Next Level – June 17, 2014 What are some document management services/document version control applications out there? Two great options that we recommend are Git and SVN . Git: http://git-scm.com/ Git is a free and open source distributed version control system designed to handle everything from small projects to very large projects with speed and efficiency. It offers a variety of exclusive features such as cheap local branching, convenient staging areas, and multiple workflows. SVN : http://subversion.apache.org/ Apache Subversion is a full-featured version control system originally designed to be a better CVS . Subversion has since expanded beyond its original goal of replacing CVS , but its basic model, design, and interface remain heavily influenced by that goal. Even today, Subversion should still feel very familiar to CVS users. For more information on what CVS is, refer to the following link: http://ximbiot.com/cvs/ svn: Working copy '' is missing or not locked Problem: While doing a svn update , you get the following message: “svn: Working copy ‘[filename]’ is missing or not locked” Cause: The directory that the file [filename] is in needs executable (i.e. list) permission on for the user that issues the command. Solution: Set the execution permission, e.g. chmod +x [dir_that_contains_that_file] CSS and Web Design Learning about CSS CSS , or Cascading Style Sheets, have taken over the design end of websites, it seems. I’m not that good with them yet, so I’m starting to collect useful CSS Links. http://css.maxdesign.com.au/ – Great site to learn CSS . Straightforward to find available topics. http://www.csszengarden.com/ – an amazing demonstration of what can be accomplished visually through CSS -based design. Each link on the side shows exactly the same text with a completely different CSS design and layout. http://businesslogs.com/design_and_usability/my_5_css_tips.php http://del.icio.us/tag/css Here is a list of Books that were recommended thru the CWP group. 1. Designing With Web Standards – Jeffrey Zeldman 2. CSS Definitive Guide OR http://proquest.safaribooksonline.com/0596527330 has a ton of info — better as a reference than to just read since it’s information overload – it covers all sorts of minute details on CSS and is guaranteed to give you a headache.(Sue) 3. CSS Cookbook by Christopher Schmitt - 4. The Zen of CSS Design : Visual Enlightenment for the Web is a great book for design ideas from a more artistic than technical standpoint. 5. Web Developers Handbook 6. Bullet Proof Web Design : Improving flexibility and protecting against worst-case scenarios with XHTML and CSS (Paperback) by Dan Cederholm (Author) 7. CSS Mastery : Advanced Web Standards Solutions (Paperback) by Andy Budd (Author), Simon Collison (Author), Cameron Moll (Author) Also, don’t forget that UCLA has access to Safari Online Proquest ) which lists 5 or 6 books on CSS that you can read online for free from a UCLA computer (or using the VPN from off-campus).(Sue) What sort of menus can I make with CSS? There are practically no limits to what you can do with CSS , the trick is figuring out how to make it do what you want! Or another way of looking at it is: what sort of ideas can you come up with to use CSS in a new (and hopefully useful) way? Here are just a few common things you’ll see sites do with CSS : Drop-down menus that show up when you hover your mouse over them Pull-up menus, that go up instead of down Horizontal menus Nested hierarchical menus Menus with images in them Stylized borders Tons of great examples can be found here: http://www.cssplay.co.uk/menus/index.html Top Ten Web Design Mistakes of 2005 By Jakob Nielsen: http://www.useit.com/alertbox/designmistakes.html The importance of "!important" in CSS Normally, CSS works by having the most recently-declared rule take precedence. However, this isn’t always the case. Rules can be followed by the expression “!important” to give them precedence over later rules. This can come up a lot in systems like Plone, where a large amount of CSS has already been written, to which you make your own additions. The existing CSS may use !important rules which will override any rules you declare, no matter where you place them. Needless to say, this can be very confusing, since it goes against what most of us have been taught about CSS . Most of the time, you’ll be using !important to get your new CSS to override some existing rules that have been declared !important. An example usage would be: p { font-size: 10px !important; } This makes sure that later CSS , including user stylesheets that browsers sometimes apply, does not override this rule. However, many times you’ll want to override a rule that has already been declared !important. To do so, just make your new rule !important as well, and place it somewhere after the rule you want to replace. Internet Explorer 6 and earlier versions do not recognize the !important rule. If you are trying to override someone else’s !important rules, this does not matter much, since your later rules will override them no matter what. However, if you are trying to create new rules that user stylesheets won’t override, you’re out of luck. IE7 should fully support the rule. The official W3C word on !important can be found at: http://www.w3.org/TR/ REC -CSS2/cascade.html#important-rules Number 4 out of Ten CSS tricks you may not know mentions the lack of !important support in IE6, and how it can be used to feed it browser-specific code. CSS Design Concerns for IE6, IE7, and Firefox Below is the beginning of (hopefully) an ongoing collection of design-related CSS issues concerning different browsers. For this initial posting, I focus on Firefox, IE6, and IE7. The good news regarding IE7 is that a lot of bugs were fixed. See the following for a list of fixes. Unfortunately, those improvements leave a fairly large gap between how IE6 and IE7 render the same CSS . See http://kimblim.dk/csstest/ for a good look at CSS testing of Selector and Pseudo-selectors for Firefox, IE6, IE7b3, and Safari. You will notice that IE7 and Firefox display more similarly than IE7 does with IE6. If you looked through the above site, you noticed that IE6 did not properly display any of the Selectors and Pseudo-selectors that were tested. In an effort to demonstrate some of the steps that can be taken to make the same page (or element within a page) display similarly across IE6, IE7, and Firefox, I listed some workarounds (min/max-width, inline vs. block-level elements) for a few of the tested Selectors and Pseudo-selectors. You will find them at: http://www.sscnet.ucla.edu/ssc/lederman/browser_design_issues_1.html. Some general ways to deal with IE6: In an effort to have your web pages validate, use Conditional Comments to write browser specific rules/code, etc. You can find more info at: http://msdn.microsoft.com/workshop/author/dhtml/overview/ccomment_ovw.asp. When using Conditional Comments, make sure that the links for them come later than the main CSS file link in the coding, AND that the rules within the Conditional Comment have at least the same or higher specificity than any similar rules in the main sheet. Otherwise, the rules in the Conditional Comments will not override the main CSS . Though not an ideal solution, hacks can be helpful at times. A list of CSS hacks. Two common hacks, the Star HTML hack and the Underscore hack, both IE-specific, (you can see a list of common hacks specific to which browsers at http://www.centricle.com/ref/css/filters ), can be avoided using the following approach: Write a rule, adding the IE-specific declaration. .title h3 { height: 21px; } After each rule, add a second rule using a child selector. This is key because IE6 will ignore this rule, but Firefox and IE7 will apply it. .title h3 {height: 21px; } .title > h3 {height: auto; min-height: 21px; } Though this leaves your CSS a bit bloated, it is an approach that avoids using these two common hacks in favor of a CSS -based solution. I should note that I haven�t tested this approach yet using really complicated coding. I�ve read that the above method requires you to be operating in strict mode, however, I found the method to work just fine (as far as I tested it) while in transitional mode. Test away! Forcing a page break with CSS Here is a simple style sheet method for making a web page have page breaks, or form feeds in it. Example: Try going to the following example page and printing it. It will come out on two separate pages. http://www.sscnet.ucla.edu/test/formfeed.htm Source Code: 1. Form Feed Test2. 3. 4. 5.

Page 1

6.

7.

Page 2

Explanation: Line 2 is where you set up your style sheet definition. Line 6 shows what you put wherever you want a page break. What's a solid starting point (global reset) for a CSS file? Browsers often have different ways of rendering the same element. For example we expect lists to be left-indented. Firefox does this by applying a left padding of 40 pixels to an unordered list (
    ). Either Opera or Internet Explorer acheives the same effect by applying a margin of 40 pixels. Now this is fine and dandy if you don’t want to change that indent value. Let’s say you test in Firefox want to pull the list back a little so you: ul { padding-left: 30px;} Looks good… until some other browser adds that 30 pixels of padding onto their 40 pixels of margin. Crap. The original solution proposed was simple and elegant: { padding:0; margin:0; } It also broke forms and obviously is not inclusive of everything for a true “global whitespace reset.” You can read more on this implementation (which was revised) on the now classic leftjustified.net post. Yahoo! have their own CSS Reset , which has a broader scope. Not sure setting h1 through h6 at 100% is an improvement over default behaviour though. ^^ An alternate (still in progress) reset is up at Eric Meyers website , and has evolved through a couple comment heavy blog posts. UX Team ( UCLA Library - Digital Initiatives & Information Technology ) The UX Team is charged by the UCLA Library Digital Initiatives & Information Technology leadership to improve the user experience of all library digital interfaces by Adopting an improved and systematic UX process on new projects/products Auditing and remediating legacy applications Maintain that capability by moving from Stage 3 to Stage 4 in the maturity model UX prior to coding Design as problem-solving process (driven by data, goals) not just style and form Increase repertoire of UX tools Expand UX team Achieve official designation add new roles and membership UX champion in upper management UX Team Joshua Gomez Tinu Awopetu Ashton Prigge Sharon Shafer Hi, are there any UCLA style resources or style guides for websites? Edit: 9/7/2012 UCLA released Brand Guidelines 1.0 in March 2012. The document contains guidance on things like fonts, colors, tone, photography, and design. There are new colors and a lot of colors got discontinued, like all of the greys. UCLA also released the templates for the web gateway in HTML only. They are available here: www.images.ucla.edu . UCLA employees will be able to log in via their Bruin Online ID. If you’re not an employee (ie you are student or a volunteer), you will need to register for an account. —Sirinya Tritipeskul Matute, UCLA Fund Here is the website for the UCLA Graphic Identity: http://www.identity.ucla.edu/ It has information on the UCLA Logo and colors. I would suggest you visit The UCLA Campus Web Publishers ( CWP ): http://cwp.ucla.edu/ There you will find many resources including the above site. UX Resources http://ux.stackexchange.com/ https://www.reddit.com/r/userexperience/ http://uxmyths.com/ What to do when CSS stylesheets refuse to apply There are a number of common mistakes users make when writing CSS stylesheets that are difficult to debug. Because browsers differ in how picky they are about errors, pages may look fine in some browsers but wrong in others. A common symptom of these problems is large sections of your page that seem to have no styles applied to them at all. One mistake when writing CSS is to comment your stylesheets using the hash sign (#), which is used in many languages such as Perl and Python to denote comments. In CSS , however, it’s used as an ID selector, meaning your “comments” will be interpreted as strange CSS . The proper way to comment CSS code is to use C-style comments, which begin with /* and end with */ . They do not have to begin and end on the same line, but take care not to nest comments. Another mistake is omitting the semicolon (;) after each attribute. You don’t need semicolons after selectors or brackets, just after assigning attribute values such as border: none; . Some browsers are fine without semicolons, others are not. To be safe, always use them. Finally, try adding the phrase !important at the end of a rule that refuses to apply, right before the semicolon. (For users of IE 6 and below, don’t bother, this keyword isn’t supported.) See the importance of !important in CSS for an explanation why. A great resource when debugging tricky CSS problems is the W3C CSS validator: http://jigsaw.w3.org/css-validator/ Here’s another: Will the browser apply the rule(s)? Web Accessibility Resources This article is a resource list to help Web developers design sites that are accessible to persons with disabilities. The list will evolve as technology changes, and also in response to issues raised by UCLA Web developers. It will be further supplemented by other materials produced by the UCLA Disabilities and Computing Program . See also other articles in this Knowledge Base under the “accessibility” tag. UC System Accessibility “Accessible Web Design Resources ": http://www.ucop.edu/irc/itaccessibility/resources/ This will collect best practices for Web designers across the UC’s. For those already familiar with basic accessibility concepts, the Design Tips and Technical Topics pages will be the most immediately useful. WebAIM Web Accessibility In Mind (WebAIM) at Utah State University has emerged as a leading reference site for many accessibility topics.: Introduction to Web Accessibility from WebAIM Resources from WebAIM , including Evaluating Web Sites for Accessibility with the Firefox Web Developer Toolbar ; The WAVE Accessibility Tool , and many more. Others World Wide Access: Accessible Web Design (University of Washington, DO-IT Program) “Accessibility tagged articles from 456Berea Street blog ": http://www.456bereastreet.com/archive/categories/accessibility/ (current issues in accessibility and usability) Sass versus LESS Quoting, "One of the hot new trends in web design is CSS pre-processed languages and there’s two big ones vying for your attention—LESS and Sass. LESS and Sass are both ways of writing CSS code with a syntax that allows you to use features not yet available with Cascading Style Sheets ( CSS ), such as variables, nesting, conditionals, and more. Pre-processed CSS languages add features to CSS that aren’t there yet—like variables, conditionals, and functions. They’re called pre-processed, because their final step is a processing, also called compiling, that converts the pre-processed language to regular CSS . In a nutshell, what you use on your site ends up being plain vanilla CSS , but comes as a result of processing the LESS , Sass, or other pre-processed language files you create." via Lynda.com blog Review links— http://coding.smashingmagazine.com/2011/09/09/an-introduction-to-less-and-comparison-to-sass/ http://css-tricks.com/sass-vs-less/ http://www.hongkiat.com/blog/sass-vs-less/ http://blog.lynda.com/2012/07/20/an-introduction-to-less-and-sass-pre-processed-css-languages/ Lynda.com has modules on the topic— CSS with LESS and Sass , http://www.lynda.com/ CSS -tutorials/ CSS - LESS - SASS /107921-2.html Responsive CSS with Sass and Compass , http://www.lynda.com/ CSS -tutorials/Responsive- CSS -Sass-Compass/140777-2.html Resources— http://sass-lang.com/ http://lesscss.org/ http://incident57.com/codekit/ http://gruntjs.com/ http://compass-style.com/ http://css-tricks.com/semantic-class-names/ http://codepen.io/ My webserver has died! How do I bring it back online in a hurry? The obvious answer to this is to restore your backup onto a spare server. Or if it’s just a drive failure, the answer would be to restore your backup onto your spare drive. But since you’re reading this instead of restoring your backup, let’s assume that the situation is not quite so simple. So here’s a hypothical situation: You’ve just launched a new website and your web server has decided that now is the time for a drive failure. The rest of the server hardware is just fine, but you don’t have any spare drives lying around and you don’t want to venture out into the LA traffic to buy a new drive. Fortunately, you do have a recent backup of your data. Or if not, your disk is not quite dead yet and you’ve read my other article on how to make an emergency backup . (There’s more than one way to go about this… but I’m just going to detail what I’ve done before) Some simplifying assumptions: Your server was running Debian Linux… this is actually sort of flexible… the general idea still works with other Linux distros, but you may need to tweak some paths or configuration files You have (or can borrow) another server that has spare disk space and is capable of doing NFS exports (this server is currently in use and you can’t just switch it to the IP address of the server with the failed drive) Here’s the plan: Download a Live CD version of Ubuntu Linux and boot the server with the CD. This way you won’t need a functioning hard disk for the server to keep working. Restore your backup to another server with enough disk space to hold your web and database data. NFS mount the backups to the server that is now running off of the live CD. symlink the web root, database data directory, and apache configuration files into where they were originally located restart the web and database servers cross your fingers and hope that it will work The details: Ubuntu I’m going to assume that getting and booting Ubuntu is not a problem… the standard download should be a live CD version General notes: the default password for the automatically logged on “ubuntu” user is blank to switch to root, type this: “sudo -s” … the password is the same as the password for the ubuntu user to install packages, use Synaptic (on the menu: System ? Administration ? Synaptic) or use apt-get from the shell: apt-get install package_name After you boot into Ubuntu, there a few things you need to do: change the user password (I’m not sure if this is necessary, but a user with a blank password makes me nervous): to do this, just open a shell session and run passwd Change the network configuration to match your old server. There’s a graphical tool for this in the menu: System ? Administration ? Networking change the IP address information, DNS settings, etc. … also change the hostname Log off and log back on… but don’t reboot! (this seems to be necessary after changing the hostname or strange things happen) NFS You’ll need to install a few extra packages on the live CD server: (also install whatever dependencies come up) For NFS : nfs-common portmap For MySQL, PHP , and Apache: mysql-common mysql-client-5.0 mysql-server-5.0 php5-mysql (note that this also installs PHP and Apache because they get pulled in as dependencies) Setup a NFS export on the spare server (this is where you restored your backup to) If you don’t have a NFS server installed, here are the packages you need for Debian: nfs-kernel-server nfs-common portmap Server configuration: Add an export to /etc/exports: /path/to/restored/backup 123.123.123.123(rw,async,no_root_squash,insecure_locks) change the IP address to the address of the live CD server this configuration is fairly insecure… but it’s restricted to just one server, and this setup should only be temporary while you get a replacement drive reload the exports with this command: exportfs -a Setup the client side of the NFS export (this is on the live CD server) make a directory to mount the restored data to: mkdir /mnt/restore edit your /etc/fstab file and add this: spare_server_hostname:/path/to/restored/backup /mnt/restore nfs rw,rsize=4096,wsize=4096,hard,intr,async,nodev,nosuid 0 0 mount it: mount /mnt/restore Server and Filesystem Shenanigans The following is all done on the live CD server Stop the web and database servers: /etc/init.d/mysql stop /etc/init.d/apache2 stop Make symlinks: make a symbolic link to wherever your web root was originally located (erase any existing directory first) symlink to your database data directory: cd /var/lib rm -Rf mysql ln -s /mnt/restore/var/lib/mysql fix the debian mysql maintenance account password: cd /etc/mysql rm debian.cnf ln -s /mnt/restore/etc/mysql/debian.cnf symlink to your original apache configuration: cd /etc rm -Rf apache2 ln -s /mnt/restore/etc/apache2 Fix any ownership weirdness: The user ID’s on the live CD and the original server may not all match up, so we need to make the ID’s match up with the live CD: chown -R www-data.www-data /mnt/restore/path/to/webroot chown -R mysql.mysql /mnt/restore/var/lib/mysql note: don’t chown the symlinks because it’ll only change the symlink (and not the underlying files) The big moment…: start up your servers: /etc/init.d/mysql start /etc/init.d/apache2 start if you’re lucky, you’ll have no error messages Apache might give some errors for missing modules. You can either install the missing modules (using apt-get or synaptic) or disable the modules if they’re not used: a2dismod name_of_module Now go check that your site is actually working properly. If it’s not working… figure out what’s wrong and add your solutions to this article. (please! :-) ) XML Introduction to XML in Flash - Making Flash Dynamic The following pages will help you get started with using XML in Flash. You will learn the basics of what XML is and how it can be loaded into, used within and sent out of a Flash movie. http://www.kirupa.com/web/xml/index.htm This can also be used as an alternative to rotating images on web sites that normally rely on JavaScript. XML Resources Books For Learning XML : CodeNotes for XML by Gregory Brill (Editor) ISBN : 0812991915 XML In a Nutshell by Scott Means, Elliotte Harold – O’Reilly and Associates Online Tutorials W3 Schools Good idea to disable popups because there’s a lot of advertising here. Editors Oxygen – for OSX , Java app so should run anywhere. This article was originally posted on the UCLA Programmers Wiki. XML XML Microsoft XML Notepad (free download) http://www.webattack.com/get/xmlnotepad.shtml XML is Too Hard for Programmers http://www.tbray.org/ongoing/When/200x/2003/03/16/ XML -Prog Why XML Doesn’t Suck http://www.tbray.org/ongoing/When/200x/2003/03/24/XMLisOK XML Protocol Comparison Matrix http://www.w3.org/2000/03/29 - XML -protocol-matrix How do we parse XML ? Perl XML ::LibXML, XML ::Parser, XML ::Twig, XML ::XPath http://perl-xml.sourceforge.net/faq/ http://www.oreilly.com/catalog/perlxml/ PHP “Parsing XML with PHP ” article http://www.zend.com/zend/art/parsing.php Function Documentation http://www.php.net/manual/en/function.xml-parse-into-struct.php Water web services language http://www.waterlang.org/ Apache - XML Editors A comprehensive list of XML schema editors and validators can be found at http://www.xml.com/pub/pt/2 —Jose Plone Why is it important to use short names in Plone? Short names become apart of the URL for Plone sites. Instead of an auto generated URL , you can create an easy to remember URL . For example, say you created a “General Information” page, your URL can show up like this: generalinfo or general-info, as opposed to something like this: 2006-05-11.1561651564. Also notice how underscores are not used in creating short names. The reason is for functionality: underscores disappear when you email the link (most word processors will format the text to become a URL so it’ll highlight and underline the text), the second reason is because it’s hard to explain to a person what an underscore is. Check out Plone’s road map for more in info: http://plone.org/products/plone/roadmap/73 To enable short name editing, see this article: https://kb.ucla.edu/link/217 Plone CMS Resources Plone is an Open-Source Content Management System built on Python and Zope. Departments at UCLA currently using Plone Office of Instructional Development Social Sciences Computing Psychology IT Department The School of Engineering UCLA Chancellor UCLA Executive Vice Chancellor and Provost For a list of sites using it UC-wide, visit http://plone.ucla.edu/links/ucplonesites/ Does Plone do what I’m looking for? I’m evaluating a system to do X, Y and Z, can Plone do that? Is Plone the right tool for the job? http://plone.org/documentation/faq/is-plone-for-me Useful Links http://www.plone.org/ PHP with Plone Plone and MySQL Integration UCLA Plone Users Group UCLA’s Plone Mailing List Plone Support and Mailing Lists For those of you still trying to figure out where everything is in Plone and how to change its look – Tutorial 18 Things I Wish Were True About Plone by Alexander Limi – Co-Founder of Plone GloWorm A great tool that works similar to Firebug but for Plone. Check out the video. Amazing. The Future of Plone’s User Experience Weblion Penn State has done an amazing job at implementing Plone on their campus. Their support and documentation is amazing and they’ve done this through Weblion. I find myself constantly using their wiki ( https://weblion.psu.edu/trac/weblion/wiki ) for references on Plone. Mike Takahashi WebServerAuth – Shibboleth Integration WebServerAuth, which replaces apachepas and AutoMemberMakerPasPlugin, allows Plone to delegate authentication concerns to a web server like Apache or IIS . Using WebServerAuth, Plone can be configured so any user known to your LDAP , Kerberos, Shibboleth, or Pubcookie system—or any other system for which your web server has an authentication module—can transparently log in using enterprise-wide credentials. Useful References for Plone and Zope The Definitive Guide to Plone – The complete book online. Great resource for Plone. Essentially the “Plone Bible”. Mike Takahashi August 19, 2005 The Book of Zope – a good book to help get you familiar with Zope. It’s a little out dated (ignore the DTML references). However, it really goes into depth on the inner workings of Zope (acquisition, ZCatalog, roles, permissions, etc.) and is something everyone should learn if you plan to customize and develop your Plone site. Online, the The Zope Book is a nice free resource. A little outdated, but the same principles still apply. Ignore the DTML sections as any customizations you do with Zope/Plone should be with TAL /Python. This section is a must for learning TAL (quoted with permission from Mike Takashi email Feb. 6, 2007) http://del.icio.us/tag/plone Plone Podcasts Plone at Disney – Interview with Scott Kelley “Users managing content with Vignette was becoming expensive from a licensing and training cost point. Installing Enfold Server to run Plone on Windows was the stategy Disney’s Enterprise Operations team took to offloading content creation and security management to individual business units. Then re-integrating the content back into their intranet.” Rob Miller from Burning Man on Plone Alan Runyan on Plone and Enfold Systems Plone Impressions – A Video Podcast About Plone Plone Presentations UCCSC 2007 Conference Plone Presentation – by Mike Takahashi Plone 4 Tips and Tricks: Table of Contents Tiny MCE Adding a color picker to the toolbar How do I identify the stylesheets in Plone? In Plone, you can list, debug, enable and disable and change the order of all the stylesheets by: go into ZMI (Zope Management Interface) go to Root Folder of your site click on portal_css ( CSS Registry). There you’ll see a long list of all the CSS’s affecting your site How to get rid of icons in Plone Plone’s default style calls for an assortment of eye candy to decorate links, list items, and various other elements. Sometimes users don’t want to see these icons. Plone makes it easy to disable any of these individual elements, but sometimes tracking down all the icons can be difficult. There are three places icons may appear in your site: Site actions (top right of the content pane, items such as print) Link decorations (for example, the globe next to external links) Portlet item decorations (such as events and news) Disabling any type of icon must be done in the ZMI . Disabling site action icons In the ZMI , go to /portal_actions. You’ll see a list of all actions. Simply uncheck the “Visible?” checkbox for each icon you want to get rid of. Disabling link decorations Slightly more complex than site actions. In your ploneCustom.css, add a CSS rule for any link type you want to disable: set the background to “none” and the padding to zero. Here is an example: .link-parent { @ background: none;@ @ padding: 0;@ } Here is a comprehensive list of all special link styles: “.link-parent, .link-user, .link-external, .link-https, .link-mailto, .link-news, .link-ftp, .link-irc, .link-callto, .link-webcal, .link-feed, .link-comment” You can simply turn this list into a CSS rule like so: .link-parent, .link-user, .link-external, .link-https, .link-mailto, .link-news, .link-ftp, .link-irc, .link-callto, .link-webcal, .link-feed, .link-comment { @ background: none;@ @ padding: 0;@ } All your link icons should now vanish. Disabling portlet icons This is much trickier than disabling other icons. What you must do is customize whatever portlet whose icons you want to remove. Manually edit that portlet code to remove icon images. All portlets can be found in /portal_skins/plone_portlets. For example, to remove the icons from portlet_events, find this line: and remove it. Other portlets should have similarly-defined icons. As you can see, there is no easy way to disable all icons at once in a Plone site, but hopefully this article will provide a good checklist for places to check. Importing and exporting a Plone site Zope has a feature that allows you to export files, folders, and even Plone sites using the Import/Export button. However, it’s important to note that this tool should not be used as a migration tool when moving an older Plone site to a newer one. For example, you have a Plone 2.1 site that you want to export and then import into a Plone 3.x site, then upgrade it. This will not work. Import/Export only works with identical systems. This means that both Zope instances must be identical. Down to the same version of Zope and the same Products installed. A complete mirror. The correct way to upgrade a site is to move the Data.fs file. For more information, go to: http://plone.org/documentation/manual/upgrade-guide Installing Plone v3.2 on Mac OS X 10.5 Installing Plone v3.2 on Mac OS X 10.5 Instructions to install Plone v3.2 on Mac OS 10.5 Server and client. Plone is a Python-based, multi-platform content management system.  If you’ve stumbled on this document not knowing what Plone is, please take a look at the project site: Plone.org .  The current recommended method of installing Plone is with the Unified Installer .  The Unified Installer will download and install the necessary components for Plone to run. Plone Downloads Page In most cases the Unified Installer will suit your needs.  However, if you require more fine-tuned control over the base components, or are looking for a better understanding of the stack which forms Plone, this document will lay the groundwork to deploy Plone on Mac OS X 10.5. Before installing Plone you should take some time to think about your system and how you’re going to be using Plone.  If you are using buildout , you are likely setting up a production or development environment.  Consider mapping out your needs (services such as authentication, backup, and product installations) and infrastructure necessary for the installation. These instructions will work on both Mac OS 10.5.x client and 10.5.x Server.  They assume you know how to create users and have a basic understanding of the command line.  Where appropriate, I will reference online documentation that has helped me with my deployment. What you will need: A computer running Mac OS 10.5 Server or client. Mac OS X Developer Tools Python 2.4.x These instructions cover the following steps Preparing To Install Creating Plone User Account Creating Plone Root Directory Installing Python v2.4 Housekeeping and Setting Proper Paths Installing “Easy Install” Installing PIL & ZopeSkel Installing Plone Additional Steps Preparing To Install The initial steps to installing Plone are done in your administrator account.  If you haven’t done it already, install the Apple xCode Developer tools that came with your installation of 10.5.  If you want to check for the most recent version, go to Apple’s Developer Website and sign up.  You can download a free copy and install it immediately. If you are not logged in as your administrator, then do so. Creating Plone User Account Before you begin, you need to create a “non-privileged” user account that will be used to both launch and maintain your Plone buildout.  This document does not go into user creation, but the key point here is that the account should be a staff account with no elevated privileges.  For the purpose of these instructions, I will call the user account and store its home directory in /Users/plone. Creating Plone Root Directory Plone can be installed in any directory on your filesystem.  If this is a merely a local install for your own development you could easily install it somewhere such as /Users/Shared.  However, if this install will be for production services you should consider installing it on a non-system drive.  The only requirement is that the user must be able to access the folder.  So on a system with two drives, say: systemDrive and dataDrive, the following commands would create a working directory for your Plone buildouts: sudo mkdir -p /Volumes/dataDrive/ploneBuildouts sudo chmod 750 /Volumes/dataDrive/ploneBuildouts sudo chown plone:admin /Volumes/dataDrive/ploneBuildouts Note: Do not think of your ploneBuildouts as a typical web server.  The files do not need to be world readable as it is the user that accesses and serves out the contents of the zodb files.  You could also easily create a Plone development group that contains your Plone developers/administrators and grant them limited access to restart and troubleshoot the instance via the sudoers file. Installing Python v2.4 Mac OS 10.5 comes pre-installed with Python v2.5.  Unfortunately, Plone requires Python v2.4.  We will have to download and install version 2.4 as an alternate install.  This is quite easy and only takes a few minutes. Note: When compiling code on Mac OS 10.5, it is always best to install your custom-built binaries in alternate locations on the filesystem rather than installing over the Apple installed versions. Doing the latter could break some dependencies and, in some cases, it is possible that Apple’s Software Update may overwrite your custom-built binaries.  Install in locations such as /usr/local or /opt. Open Terminal and enter the following commands: ls /usr If the ls command does not list a directory called local you will have to create it and some subdirectories with the following commands: sudo mkdir -p /usr/local/include sudo mkdir -p /usr/local/lib sudo mkdir -p /usr/local/bin The first time you run sudo you will be asked for your administrator password.  Go ahead and enter that and press return. Next you will need to get the Python source code.  Typically I compile code from a working directory that I download the source to.  (If you don’t have a working directory and want to create one mkdir ~/working from Terminal will create it for you. From Terminal cd into your working directory: cd ~/working .  Using curl, download the source code from Python.org . Note: You may want to check to see if any newer, stable versions of 2.4 exist and download accordingly. In Terminal enter: curl -O http://www.python.org/ftp/python/2.4.6/Python-2.4.6.tgz Since this is a compressed file we will need to uncompress it: gnutar -xzf ./Python-2.4.6.tgz GNUTAR will create a folder called Python-2.4.6.  CD into it: cd ./Python-2.4.6 . The following command will compile and build Python-2.4.6 on your system.  Each command will take a few minutes to complete and report any errors if there are any: ./configure MACOSX_DEPLOYMENT_TARGET=10.5 --disable-tk make sudo make altinstall Once sudo make altinstall completes, Python v.2.4.6 will be installed on your system but will not affect any applications that might use the default install of v2.5. You can now log out of your administrator account and login to the account.  All the remaining work can be done remotely via ssh . Housekeeping and Setting Proper Paths Before continuing, we need to do a little housekeeping in the account to make sure the proper versions of Python are accessed and that any Python egg extensions are deployed in the correct location. Login to the account either remotely or locally. The default user shell used by Mac OS X 10.5 is bash .  We will need to create a .profile file for bash to read and adjust its PATH and set the PYTHONPATH .  Use the text editor of your choice. Note:  If you insist on using a GUI text editor, I suggest TextWrangler or Smultron.  I prefer emacs from the command line as it generates a backup file in case you make a mistake.  It is always a good idea to create backup files to fall back on should a modification go wrong.  The .profile file needs to be saved in the root folder of your home directory. emacs ~/.profile PATH =~/bin:/usr/local/bin:${PATH} export PATH export PYTHONPATH =~/Library/Python/2.4/site-packages/ Note: To save your file in emacs and exit use the following key combinations: ^x^s ^x^c The next file to create is .pydistutils.cfg emacs ~/.pydistutils.cfg [install] install_lib = ~/Library/Python/$py_version_short/site-packages install_scripts = ~/bin Finally, we need to make the directory Python will store its eggs in: mkdir -p ~/Library/Python/2.4/site-packages Logout of the account and then log back in.  To check that your PATH is set up correctly type: which python2.4 If /usr/local/bin/python2.4 is returned your path is set correctly.   It’s also a good idea to check your PYTHONPATH variable: echo $PYTHONPATH This should return the full path to the site-packages directory we created.  Depending on where you specified the home directory to be, it may be something like this: /Users/plone/Library/Python/2.4/site-packages/ The PYTHONPATH variable tells Python2.4 where to install or find any eggs necessary to operate. Installing “Easy Install” Easy Install is a utility that Python uses to download, build, install and manage Python packages.  The utility is well documented on the developer’s website: Python Enterprise Application Kit . Create a working directory to install your Python packages from and CD into it. mkdir ~/pythonInstallScripts cd ~/pythonInstallScripts Download Easy Install. curl -O http://peak.telecommunity.com/dist/ez_setup.py Once the download has finished you can install with the following command: python2.4 ez_setup.py This will download and install the Setuptools Python egg in the account’s ~/Library/Python/2.4/site-packages/ directory.  It will also create a directory in the home folder called bin .  If you cd ~/bin you will find the easy_install binaries when you ls the directory: easy_install easy_install-2.4 You will see two versions of easy_install .  You need to use the version of easy_install specific to the version of Python you are running.  In our case, this is easy_install-2.4 .  If you don’t trust yourself to remember this you can remove execute permissions on easy_install and move it elsewhere or delete it and create a virtual link. cd ~/bin chmod 440 easy_install mkdir deprecated mv easy_install ./deprecated/easy_install.dep ln -s ./easy_install-2.4 ./easy_install Note: Apple has its own version of Easy Install in /usr/bin.  The path we set above should grab the new version, however it’s a good idea to check using which easy install.  I recommend specifying easy_install-2.4 to leave out the guess work._ Installing PIL & ZopeSkel Now that you have both Python v2.4 and Easy Install in place, you need to install PIL and ZopeSkel.  To do so, type the following commands: easy_install-2.4 --find-links http://dist.repoze.org/PIL-1.1.6.tar.gz PIL Note: You will need to download the Unified Installer and use the included PIL : PILwoTk-1.1.6.3.tar.gz easy_install-2.4 /path/to/PILwoTk-1.1.6.3.tar.gz easy_install-2.4 -U ZopeSkel It will download and install all necessary files for Zope to operate. Installing Plone Once you have installed ZopeSkel, you are ready to install Plone. CD into the directory you wish your plone deployment to live.  In our case it is /Volumes/dataDrive/ploneBuildouts . cd /Volumes/dataDrive/ploneBuildouts Your Plone instance will need a name for the directory it is stored in.  For purposes of this documentation, we’ll call it demo .  At the command prompt enter: paster create -t plone3_buildout demo You will be asked a series of questions.  For now the default answers will suffice, but be sure to set a non-trivial password for your Zope root admin user. Selected and implied templates: ZopeSkel#plone3_buildout  A buildout for Plone 3 projects Variables: egg:      ploneWeb package:  ploneweb project:  ploneWeb Enter plone_version (Which Plone version to install) [‘3.2.1’]: 3.2.1 Enter zope2_install (Path to Zope 2 installation; leave blank to fetch one) [‘’]:  Enter plone_products_install (Path to directory containing Plone products; leave blank to fetch one) [’‘]:  Enter zope_user (Zope root admin user) [’admin’]:  Enter zope_password (Zope root admin password) [‘’]:  Enter http_port ( HTTP port) 8080:  Enter debug_mode (Should debug mode be “on” or “off”?) [’off’]:  Enter verbose_security (Should verbose security be “on” or “off”?) [‘off’]:  Note: Be sure to set a non-trivial password for the admin account. Note: If you specify a HTTP port other than 8080, you should verify that the port is open in /etc/services and not in use by another service.  If not, you’ll need to  append the port information to the /etc/services file. Once paster has finished, cd into the demo directory and run the bootstrap.py script. cd ./demo python2.4 ./bootstrap.py Note: The bootstrap.py script needs to be run only once per Plone instance. The bootstrap script will build the rest of the files necessary to install Plone.  When it has completed, you must run the buildout.cfg file created by the bootstrap script to install Plone. ./bin/buildout -v Note: To customize your Plone installation, you can modify the buildout.cfg file to include products that extend Plone’s capabilities. Once buildout has completed you can launch your Plone instance by running the following command: ./bin/instance fg Note: The fg flag tells Plone to run in the foreground, posting debug information to the console.  It’s a good idea to test your install in debug mode to make sure Plone comes up cleanly.  If you wish to start Plone in daemon mode, use ./bin/instance start. Plone should now be up and running.  To connect to your instance, open a web browser and connect to: http://yourHostName:8080/manage This will take you to the Zope Management Interface.  Login with your admin account.  In the right hand side of the main content window, you’ll see a drop down menu labeled: Select Type To Add .  Select Plone Site and click Add .  A dialog will appear, enter the following info: ID : Site container name, think of this as the directory holding your site. This will appear in the URL path. Title : Your Website Name Description :  Optional Information Describing the site. Once you fill out this information click the “ Add Plone Site ” button and your site will be created.  To visit your site point your web browser to: http://yourHostName:8080/ID where ID is the site ID you set when you added the Plone Site. Additional Steps Now that you have a standard install of Plone.  You can begin modifying the setup by editing the buildout.cfg file and/or adding products to the Products directory. Some third-party Products for Plone require additional libraries to be bound to Python, or installed as packages to Python; this is beyond the scope of this document at this time. Some excellent sources of information include: Plone CMS : Open Source Content Management Weblion Zope.org Python Programming Language This documentation wouldn’t have been possible without the excellent tutorials at PSU’s Weblion and Plone.org . Remove highlighting of search terms in Plone If you haven’t noticed already, go to Google and do a quick search for your Plone site. Then click on your site. Plone will then highlight all of the searched terms. This can be helpful, but also distracting. Plone will try to match the highlight color with the over all color scheme of your site. However, if you want to disable this feature, here’s what you do: Go to the ZMI → portal_skins → plone_ecmascripts → highlighsearchterms.js Hit Customize add return false; just before function highlightSearchTerms(terms, startnode) { and function highlightSearchTermsFromURI() { Then hit save and you’re done! The adjustment below will permanently turn off highlighting for your site. On the other hand, if you only want to temporarily turn off the highlighting, simply remove “/?searchterm=mySearchTerm” from the end of the URI in the browser’s address bar. Is there a permission that allows a user edit content that s/he does not own in Plone? For Plone 2.x, 3.x Question: I notice that for a piece of content, both the Owner and the Manager can edit it. Naturally, I assumed that there a permission that allows the role Manager to be able to edit any content it does not own. However, after I assign ALL the permission to a certain role, say, Reviewer, at the Plone root level (going to the Security tab after clicking on the Plone site in ZMI ), a user with the role Reviewer is still not able to edit content that s/he does not own. So, it leads me to think that there is no such permission for editing content for other users? If that is the case, is the Manager role somehow “hardcoded” to be able to edit anything? What I want to do is to have a role that can do anything (create, edit, delete) to any content of a Plone site, yet it has no access to Site Setup in Plone or whatever features that change the technical aspects of the site. Answer: In the ZMI , click on portal_workflow, then plone_workflow. Then click on the “States†tab on the top. As a test, try modifying the published state. Click on “published†and then select the “Permissions†tab on the top. Then check “Modify portal content†for the Reviewer role. Also, once you have made the changes you must update the security settings or your changes will not go into effect. This can be done by clicking on portal_workflow and scrolling all the way to the bottom of the page and clicking on “Update security settingsâ€. Why can't I add a photo using AT Photo in Plone? If you’ve used the product ATPhoto or ATPhoto Album in Plone 2.1, but now it is breaking in Plone 2.5, before you rip your hair out, here’s what you need to do: copy the code from this site: http://dev.plone.org/collective/browser/ATPhoto/trunk/configure.zcml (you might need to clean it up a bit) log into your server and go to your Zope folder next go to /instance-home/Products/ATPhoto/configure.zcml (you might want to make a backup of this file) remove the existing code and replace it with the one you’ve copied restart Zope (you can do this via ZMI ) And volia! It’s fixed. Shibboleth For Plone Updated as of June 25th, 2010 UCLA Shibboleth 2.1+ Guides: Installation guide Configuration guide Follow up with installation of WebServerAuth: http://plone.org/products/webserverauth Does “(null)” show up instead of the login name in Plone when all is said and done? Head over to your Apache SSL configuration (/etc/httpd/conf.d/ssl.conf) and modify your RequestHeader setting of X_REMOTE_USER to utilize the Shibboleth attribute you desire: @RequestHeader set X_REMOTE_USER %{SHIBUCLALOGONID}e @ The most up to date instructions for the Shibboleth plug-ins for Plone are available from Ithaka.org: http://tid.ithaka.org/shibplone.pdf Here are older ones Thanks to Alan Brenner for creating these plug-ins and all the help. http://tid.ithaka.org/software Thanks to Datta Mahabalagiri at UCLA AIS All my paths to files are for OS X Please connect your Service Provider to www.testshib.org to make sure your installation is solid before connecting to UCLA native.logger and shibd.logger should be set to DEBUG instead of INFO … Native Logger Shibd Logger they are located here: /opt/shibboleth-sp/etc/shibboleth/shibd.logger /opt/shibboleth-sp/etc/shibboleth/native.logger …for the log files located here /opt/shibboleth-sp/var/log/httpd/native.log /opt/shibboleth-sp/var/log/shibboleth/shibd.log Check that you have the correct Attribute Acceptance Policy for the UCLA Identity Provider /opt/shibboleth-sp/etc/shibboleth/ AAP .xml AAP .xml Verify you have the correct metadata for the UCLA Identity Provider /opt/shibboleth-sp/etc/shibboleth/ucla-metadata.xml UCLA Metadata mine is in the md namespace Setup your Shibboleth.xml like so: shibboleth.xml here is my example vhost in my httpd.conf, it isn’t that pretty. vhost.conf or check out what Alan Brenner did Alan’s Vhost Make sure your Service Provider is receiving attributes correctly though a simple phpinfo() page or this page that can display Shibboleth attributes Here is mine https://test.psych.ucla.edu/secure/ Here is the code I found on google Check Attributes Page First Install ApachePAS plugin http://plone.org/products/apachepas Then Install the Shib Plugins AutoUserMakerPASPlugin ShibbolethLogin ShibbolethPermissions from here http://tid.ithaka.org/software configure AutoUserMakerPASPlugin in the ZMI at /psych/acl_users/AutoUserMakerPASPlugin to look like this http://www.psych.ucla.edu/shibfiles/autouserconf.jpg I’m only using the first two HTTP_REMOTE_USER1 and HTTP_SHIB_DISPLAYNAME you can ignore the rest of the “User Setup Headers” make sure you put whavever “User Setup Headers” you are using down below in the “User Mapping Headers” Configure Shibboleth Login at /psych/acl_users/ShibbolethLogin to look like this http://www.psych.ucla.edu/shibfiles/shibloginconf.jpg When you login to your site select the “Log in with a UCLA user id” link That’s it. Kinda rough. I don’t have a logout function yet. I haven’t gotten around to using ShibbolethPermissions yet but maybe this might get you going: http://tid.ithaka.org/software/shibbolethpermissions/ Gotcha’s “Session Creation Failure” errors were from having the wrong SessionInitiator in my shibboleth.xml “Rejected Replayed Assertion ID” were from incorrect Host and Path in the RequestMapProvider Good Luck How do I get started with designing new/existing layouts in Plone? Taken from various posts on the Plone mailing list ( http://www.nabble.com/Plone-f6741.html ) Stan McFarland wrote: “The short answer is that you can make Plone look any way you want with a combination of template customization and CSS . You just need to learn how to do it. Andy McKay’s “The Definitive Guide to Plone” is a good place to start, as well as plone.org.†J Cameron Cooper wrote: “The best way is to start with the Plone pages, which have a fairly standard and general template, and customize them with CSS . If you want to work an existing design into Plone, you will have to do some slightly trickier stuff. (Which, basically, is replacing main_template with your own structure, though preserving the “signature” of main_template.)†Peter Fraterdeus wrote: “I highly recommend that you read the docs section in plone.org as a starting place for ‘skins’ customization, and best practices for building a “site product” which will instantiate your customizations. “After that, it’s probably best to have a good look at the way that the “main_template” is constructed and how the various layers of CSS are used to modify the look of the site. (on your *nix box, try “locate CMFPlone/skins/plone_templates/main_template.pt” or find it in the ZMI ).†Matt Bowen wrote: “Plone uses Python for logic, Zope Page Templates for layout, and the Zope Object Database. If you don’t know Python, you’ll want to learn it — without it, you will be limited in your customizing. People seem to like Dive Into Python [ http://www.diveintopython.org/ ], but there are lots of good tutorials online, and it’s a very nice language. ZPT you’ll pick up from the book and the tutorials. Finally, definitely check out the many, many good plone videos on Plone.org, at http://plone.org/about/movies and http://plone.org/events/conferences/seattle-2006/presentations/session-videos . There is a lot of good stuff there about all aspects of customization.†Backing up and packing Plone's database file (Data.fs) Backing up the database See “ Backup Plone ” and “ Backup and recover Data.fs in linux ” in Plone’s documentation. Additional notes: Recent versions of Repozo can compress (gzip) the backup files in addition to doing incremental backups. When doing full backups, Repozo behaves exactly as using cp to copy Data.fs, except it uses ZODB’s code to determine where the last finished transaction is and therefore do not copy unfinished transactions at the end of Data.fs. Zope’s ZODB can use multiple “storages” (think of it as something like database backends). It comes with FileStorage (i.e. storing everything in Data.fs). DirectoryStorage is an alternative that is supposingly easier and faster to back up incrementally. Packing the database Packing a database throws away old object versions (generated by undo actions) from the database. To pack a database: Go to Zope’s admin panel, under Control Panel → Database → [database name, e.g. main], choose how much undo info to keep, and click “pack”. Note: Data.fs.old will contain a copy of the database file before packing. (There is a Zope product called PloneMaintenance that can do scheduled backup, although I have not tried it yet.) Zope/Plone usage statistics Since a Zope access log (Z2.log) has the same format as an Apache access log, Apache log analyzers will probably work for Zope/Plone too. I have tried AWStats and Webalizer and they both worked w/o needing to set anything special. I prefer Webalizer because: It’s fast. (We have a 700 MB log. Webalizer took 70 seconds but AWStats took 10+ minutes.) It’s easy to use. (No configuration was needed in my case.) Output is in the form of a bunch of static files ( HTML , PNG ), so no need to set up a CGI script just to view the stat. Should I use plonecustom.css when changing the layout for my Plone site As stated in plonecustom.css, if you are going to be making heavy modifications to your layout, you should modify each CSS file accordingly (base.css, portlets.css, etc.). plonecustom.css can be used for light modifications or any custom classes and id’s you create. Changing number of displayed news/events in Plone portlets Find out which version of Plone you are running. Versions prior to 2.5 keep their portlet code in Zope Page Templates and can be modified easily. Plone 2.5 uses a new programming method called Views that complicates things. Versions after the 2.5.x series are not covered in this guide since they haven’t been released yet, but working with these versions will likely be the same as Plone 2.5. Versions prior to 2.5 Go into the ZMI and navigate to /portal_skins/custom. If you already have a customized portlet_events or portlet_news, change the one you find. Otherwise, we’ll need to begin customizing a fresh copy. Go to /portal_skins/plone_portlets. Select the appropriate portlet you want to change (either portlet_events or portlet_news) and customize it. Look for a line near the top of the file beginning with tal:define="results . This TAL define statement goes on for several more lines. Look for the end of it, which has an expression looking like: [:5] . The number after the colon controls the number of events to display, and you can change it to whatever you like. Version 2.5 and later Because Plone 2.5 uses Views, the code that does the searching for news or events is part of the Zope server itself. You can modify this file directly if you only have one Plone site and don’t think you’ll be changing it frequently. However, this is not the best method, just the simplest. Directly modifying Zope Note: this will affect all Plone sites on your server. The code is found at: instance_home/Products/CMFPlone/browser/portlets/events.py (or news.py) in the root of your Zope install directory. Look for the code that specifies sort_limit , and change it to the number of items you want to show. Then look for a line that ends with [:5] and change the number in brackets also to the number of desired items. Save the file and restart your Zope server. Modifying the ZPT If you have more than one Plone site, and want to change the number of events on one site without affecting the others, this method is best. By borrowing some code from the old Plone version, we can make the needed changes. Customize /portal_skins/plone_portlets/portlet_events (or portlet_news) if you don’t have a customized copy already. Look for the first tal:define tag and remove it (all 4 lines, or 3 lines for the events portlet). Now replace it with this code: tal:define="results python:here.portal_catalog.searchResults(portal_type='Event', end={'query': DateTime(), 'range': 'min'}, sort_on='start', sort_limit=5, review_state='published')[:5];" (If you’re changing the news portlet, be sure to set portal_type='News Item' and remove the end= part.) Change both the number after sort_limit= and the number in brackets at the end to be the number of items you want to display. If you changed the events page, now you need to replace all occurrences of events_link with string:/events , and replace prev_events_link with string:/events/previous . (These are the default names. If you changed the names of the Events or Previous Events pages, you’ll need to use their new URLs here.) If you changed the news page, replace all occurrences of prev_events_link with string:/news . (Again, this is the default name. If you changed it, use the correct URL for the News page.) Customizing the portlets in other ways You can change sort order, sort criteria, and other things by altering the parameters to the searchResults function that we used. See the ZCatalog help page for more information. Search across multiple Plone instances If you have multiple Plone instances and you would like the search feature to search across the instances instead of only the one you are performing the search in, there is an add-on called PloneRSSSearch and it is available from the following site: http://ingeniweb.sourceforge.net/Products/PloneRSSSearch/ Another alternative is to use External Site Catalog but it is more general: http://ingeniweb.sourceforge.net/Products/ExternalSiteCatalog/ How can I undo changes in Plone? Plone has a feature that lets you undo changes you make to Plone-managed pages and other items. To access it, log in, and in your personal toolbar (usually at the bottom of the screen) there will be an “undo” link. If your site’s templated has been customized so that the undo link is no longer there, you can access it via http://your.plone.site/undo_form . The undo screen is easy to use. Simply check the box next to any change you want to undo, and press the “undo” button at the bottom. You can undo nearly any Plone action, even logins! (Not terribly useful, but maybe you can think of a use for it.) The Plone undo feature is meant to nullify recent changes. It is not a long-term archiving tool. Depending on your version of Plone, the undo history may be wiped whenever the Zope server is restarted, or when its database is compacted. For keeping important revisions permanently, Plone 3.0 will have a versioning feature. Until that time, you should make regular backups of your site, relying on the undo feature only for short-term revisions. Zope has its own more sophisticated undo feature inside the ZMI . To get to it, navigate to any object, and then click the “Undo” tab at the top of the screen. You can undo changes in just the same way as the Plone undo page. You can also view particular revisions in the object’s history by clicking the “History” tab. Keep in mind that you cannot undo changes made to Plone objects in the ZMI – you must use Plone to undo Plone changes. How do I remove the icons in Plone? This will allow you to remove the navigation icons that appear in Plone’s navigation portlet. go into ZMI (Zope Management Interface) go to Root Folder of your site click on portal_css ( CSS Registry). There you’ll see a long list of all the CSSes affecting your site disable generated.css Additionally: under “Condition” put the following: not: portal/portal_membership/isAnonymousUser (This will allow the icons to appear to users who are logged in.) How do I change the header image in Plone? Enter the the Zope interface by adding /manage to the end of your URL . Go to the folder ‘/portal_skins’ and the subfolder ‘/plone_images’. Click on ‘logo.jpg’ Click on Customize and you will be directed to the /custom folder where you can upload your logo image. For more info: http://plone.org/documentation/how-to/custom-logo If you have already changed the logo image and would like to change it to another, start in the folder /portal_skins/custom, click on logo.jpg and upload the new image. Why are my excluded Plone items still showing up in navigation? Plone comes with a useful way to hide certain items from the navigation menu. On the page’s properties tab, you can select “exclude from navigation” and the item won’t show up anymore in the navigation bar or site map. … at least, that’s what you would think. You’ll notice that if you navigate to the page you excluded (by following a link or typing in its URL directly), it will show up in the navigation again! The fix involves some Zope template code: Open up the ZMI , and customize /portal_skins/plone_portlets/portlet_navtree_macro if you don’t have it customized already. Look for a line of code about 20 lines down that says: tal:condition="python: bottomLevel <= 0 or level < bottomLevel-1"> Change the line to read: tal:condition="python: (bottomLevel <= 0 or level < bottomLevel-1) and (not item.exclude_from_nav)"> Now your item will never show up in the navigation tools as long as it’s excluded. Plone and Zope Screencasts Collection of screencasts demoing Plone functionality and ease of development in Zope 3. How to add new slots in Plone This document describes how to add an additional portlet slot to the two that exist already (left and right). http://plone.org/documentation/how-to/add-slots Restricting Plone portlets to show up only on certain pages Sometimes you may want certain Plone portlets to only show up on certain pages. This guide will walk you through doing exactly that. If the portlets already appear on your site, you’ll need to remove the portlet calls from the site properties page. In the Zope Management Interface, click on the name of your site at the top of the left-hand navigation bar. Then click on the properties tab at the top of the right-hand pane, and you’ll see a list of properties. The two important ones are left_slots and right_slots. These contain lists of portlets you want to show up in the left and right panes, respectively, of your site. Remove the lines referring to the portlets you want to appear only on certain pages. Remember to click the “Save Changes” button near the bottom when you finish. To get portlets to appear conditionally, we are going to manually add in code to the main template that references the portlets. If you have a customized main_template file in your custom folder, edit that. If not, create a customized version of main_template, found in /portal_skins/portal_templates. Find where you want the portlets to appear, and insert this code in the appropriate spot:
    @ News @
    The first div element is used to conditionally filter the pages that the portlet shows up on. Replace ('welcome', 'news') with a Python-style list (that is, strings separated by commas) of the IDs of the pages where you want the portlet to appear. The second div calls the portlet code. Replace portlet_news in the above path expression with the name of the portlet you want. The text inside the div (in this case, “News”) is just a placeholder and can be anything you want. You only need one outer div (with the tal:condition code), provided your conditional portlets are going to go in the same area. Just add an inner div with the appropriate metal:use-macro attribute for each portlet. Calling portlets in this way also gives you the freedom to place them anywhere you like, not just in the pre-defined left and right parts of the screen. Say you only want the News portlet to appear and nothing else, you can use a filler portlet, one that you know is not in use. For example: here/portlet_related/macros/portlet. But what about the pages you that you didn’t the filler to show up (for example, you have the portlet set to show up on the left hand side, but for the pages without the portlet, the text should be flushed left). It’s a little tedious, but go to the folders in the ZMI that you want the filler portlet to be removed from. Go to the Properties tab. At the bottom of the form, add a property called left_slots , with lines as the type and no content. Press add. Also, anything that is a child of the folder will also carry this property. Can Plone display content from another site inside it? Yes, there is a product that will do exactly this. It’s called windowZ . Just use the quick installer to set it up, and you can add Window objects through the Plone interface. Window objects don’t have their own content, but rather a URL that points to the content you want to display. Additionally, the external content becomes searchable within Plone’s powerful search tool. However, if the content is constantly being updated (i.e. a Blog) this will not be automatically updated. Also, the external content must be of fixed width and height because WindowZ does not support dynamic data. How can a rotating banner image be done in Plone? The first step is to create a Python script that will serve up the image you want. This article assumes that you want a random image from a folder to be chosen. Python-savvy readers can use more advanced techniques, such as making a list of images to load in the same order, etc. Through the ZMI go to /plone_skins/custom folder, and add a Script (Python) object from the drop down menu. Give this script a name (this example uses “randimg”) and put this code into it: from random import choice # Import a standard function, and get the HTML request and response objects. from Products.PythonScripts.standard import html_quote request = container.REQUEST RESPONSE = request.RESPONSE RESPONSE.setHeader('Content-Type', 'image/jpeg') # Get the current folder's contents, choose an image and return it images = context.objectValues(['ATImage']) return choice(images).data Now that the script is in place, you can test it by pointing your browser to http://your.plone.site/images_folder/randimg . (Replace images_folder with whatever your random images folder is called.) It will work just like a normal image file on a web server. To add the image anywhere in your site, add the usual image HTML : . Every time the page is reloaded, a randomly-selected image from images_folder will be shown. If you are using images other than JPEGs, you will need to change the setHeader call so its second parameter reflects the image type you’re using. For example, image/gif or image/png. Also, the objectValues function retrieves only the file types you ask it to, in this case “ATImage”, which means images uploaded through the Plone interface. Images uploaded through the ZMI have a different file type, “Image”. This is an important distinction, so change the parameter if you need to. Note however, all content should be added through Plone and not through the ZMI . All content management should be done in Plone. Working with the ZMI in this fashion can result in unforseen problems. You have been warned. An alternative is to leave the parameter to objectValues blank, so that it returns all objects in the folder. However, if you use this option, make sure your random images folder has only images in it! Update from Joel Burton on Plone.org Using ‘objectValues’ will actually retrieve each image from the folder, even though you only want to use one. Not very efficient. It also is making no checks for things like effective/expiration date. Better would be: images = context.randomimages.getFolderContents({'portal_type':'Image'}) return choice(images).getObject().data Overall, though, I’d recommend a different strategy: rather than having this script pretend to be the image, I’d have a script that returns a randomly-selected image tag . This will allow you to get a good image tag (w/height, width, alt text, etc.) from a randomly-chosen image. This would look like: from random import choice return choice(context.randomimages.getFolderContents({'portal_type':'Image'})).getObject().tag() Then, rather than having code like , you’d have your Page Template say . This will give you a good image tag of a randomly-chosen image. How do I make dynamic dropdown/pullup menus in Plone? There is a Plone Drop Down Menu product (also called qPloneDropDownMenu) that creates navigation tabs for you that have a drop-down menu behavior. The product page above has complete instructions on using it. If you want the menus to “pull up” rather than “drop down”, one line of code in the drop down CSS file can do this: Make a copy of /portal_skins/qPloneDropDownMenu/drop_down.css into your custom folder. In the custom file, add bottom: 12px; into the style for #portal-globalnav li ul . Note: your pixel mileage may vary. If your menus end up floating too high (or low, sinking into the navigation bar itself) try altering the value for the bottom attribute. You can also try using values measured in em, so that it changes depending on the font size. How do I enable the advanced mode of the TinyMCE editor for Plone? The TinyMCE editor is a feature-rich WYSIWYG editor for Plone, similar to Kupu. However, many of TinyMCE’s best features are hidden away in so-called “advanced mode”. Installing TinyMCE is straightforward – install it like you would any other Plone product. To enable advanced mode: In the ZMI , go to /portal_skins/tinymce/tinymce_wysiwyg_support. Make a copy into “custom”. Edit the file in custom. Near the top there is a line that says: — Delete this line or comment it out. In its place, add this code: Within the body of the tinyMCE.init function, you can add other lines to change the appearance of the toolbar, change its location, add more buttons, etc. Here is a reference of all the settings for the TinyMCE editor: http://tinymce.moxiecode.com/tinymce/docs/reference_configuration.html Pay special attention to the function theme_advanced_buttons<1-n>_add: you can use it to add more buttons to the toolbar. For example, to add an undo button to row 2, put this line into tinyMCE.init: theme_advanced_buttons2_add: “undo” A full list of available buttons can be found here: http://tinymce.moxiecode.com/tinymce/docs/reference_buttons.html Remember that customizing the TinyMCE editor is only possible when using the Advanced theme. Why aren't my font colors / scripts / Flash / Java applets showing up in my Plone site? By default, Plone employs an HTML -filtering system when it transforms Plone documents into marked-up web pages. Certain tags, such as and other deprecated tags in HTML , are removed so that the generated page is closer to XHTML , which does not allow deprecated tags. Other tags such as