4 | | * WSGI likes print statements to go to {{{sys.stderr}}} not {{{sys.stdout}}}: http://code.google.com/p/modwsgi/wiki/DebuggingTechniques |
5 | | * use Web2Py shell: http://www.vimeo.com/879939 |
6 | | * use [http://ipython.scipy.org/moin/ IPython] for interactive exploration (on Windows, install [http://ipython.scipy.org/moin/PyReadline/Intro PyReadline]) |
7 | | * use [http://groups.google.com/group/web2py/browse_thread/thread/cc13960a5079b2d5# FirePy] to see logging output to Console (to view with Firebug) |
8 | | * Log to a File: http://groups.google.com/group/web2py/browse_thread/thread/e20d0bd2e542aa14 |
9 | | * Debug Tools: http://docs.python.org/library/debug.html |
10 | | * Use [http://stackoverflow.com/questions/2654113/python-how-to-get-the-callers-method-name-in-the-called-method Inspect] to check which function called the one you're troubleshooting: |
| 6 | * WSGI likes print statements to go to {{{sys.stderr}}} not {{{sys.stdout}}}: http://code.google.com/p/modwsgi/wiki/DebuggingTechniques |
| 7 | * use Web2Py shell: http://www.vimeo.com/879939 |
| 8 | * use [http://ipython.scipy.org/moin/ IPython] for interactive exploration (on Windows, install [http://ipython.scipy.org/moin/PyReadline/Intro PyReadline]) |
| 9 | * use [http://groups.google.com/group/web2py/browse_thread/thread/cc13960a5079b2d5# FirePy] to see logging output to Console (to view with Firebug) |
| 10 | * Log to a File: http://groups.google.com/group/web2py/browse_thread/thread/e20d0bd2e542aa14 |
| 11 | * Debug Tools: http://docs.python.org/library/debug.html |
| 12 | * Use [http://stackoverflow.com/questions/2654113/python-how-to-get-the-callers-method-name-in-the-called-method Inspect] to check which function called the one you're troubleshooting: |
28 | | * [http://aymanh.com/python-debugging-techniques Python Debugging Techniques] |
29 | | * Insert these statements into your code |
30 | | * Get a Python shell up to explore interactively: {{{import code; code.interact(locals=locals()}}} |
31 | | * Get a full stack trace: {{{import pdb; pdb.set_trace()}}} |
32 | | * winpdb: http://groups.google.com/group/web2py/msg/ee46125b7c93fdd4 |
33 | | * WingIDE: http://www.wingware.com/ |
34 | | * Using with Web2Py: http://www.wingware.com/doc/howtos/web2py |
35 | | * [DeveloperGuidelines/Eclipse Eclipse] IDE |
36 | | |
37 | | === Reserved Keywords === |
38 | | * 'request' -> web2py internal use |
39 | | * 'key' as a db row name -> MySQL confuses it with internal keyword KEY |
40 | | * http://dev.mysql.com/doc/mysqld-version-reference/en/mysqld-version-reference-reservedwords-5-0.html |
41 | | * http://www.postgresql.org/docs/8.1/static/sql-keywords-appendix.html |
42 | | |
43 | | == CSS & Javascript debugging == |
44 | | * use Firebug: http://code.google.com/support/bin/answer.py?answer=77412&topic=12044 |
45 | | * use [http://www.sprymedia.co.uk/article/Visual+Event Visual Event] to see which events are active. |
46 | | * use Venkman: http://www.mozilla.org/projects/venkman/ |
47 | | * use Fiddler for compressed files: http://www.yuiblog.com/blog/2008/06/27/fiddler |
48 | | * http://pastebin.me (allows edits of HTML & previews) |
49 | | * http://jsfiddle.net (allows edits of JS & previews) |
50 | | * http://yura.thinkweb2.com/domlint/ |
51 | | * http://www.jslint.com/lint.html |
52 | | * IE6 cheatsheet: http://www.virtuosimedia.com/tutorials/ultimate-ie6-cheatsheet-how-to-fix-25-internet-explorer-6-bugs |
53 | | |
54 | | == Python == |
| 30 | * [http://aymanh.com/python-debugging-techniques Python Debugging Techniques] |
| 31 | * Insert these statements into your code |
| 32 | * Get a Python shell up to explore interactively: {{{import code; code.interact(locals=locals()}}} |
| 33 | * Get a full stack trace: {{{import pdb; pdb.set_trace()}}} |
| 34 | * winpdb: http://groups.google.com/group/web2py/msg/ee46125b7c93fdd4 |
| 35 | * WingIDE: http://www.wingware.com/ |
| 36 | * Using with Web2Py: http://www.wingware.com/doc/howtos/web2py |
| 37 | * [DeveloperGuidelines/Eclipse Eclipse] IDE |
62 | | * [wiki:Web2pyInternalsAndTips Web2py Internals and Tips] |
63 | | * http://web2py.com/examples/default/docs |
64 | | * Prevent HTML tags being escaped in views: {{{{{=XML("<p>Not escaped!</p>")}}}}} |
65 | | * HTML Helpers: http://web2py.com/AlterEgo/default/show/217 |
66 | | * Arbitrary HTML tags using TAG, e.g. TAG.LEGEND('a','b',_c='d') |
67 | | * HTML Helpers can be navigated/manipulated like the DOM: http://groups.google.com/group/web2py/browse_thread/thread/ac045f3b1d3846d9 |
68 | | * https://web2py.com/web2py_wiki/default/wiki/tips |
69 | | * https://web2py.com/web2py_wiki/default/wiki/widgets |
70 | | * Pagination: |
71 | | * Basic server-side pagination: http://web2py.com/AlterEgo/default/show/95 |
72 | | * Grid to replace SQLTABLE with server-side pagination included: http://www.web2pyslices.com/main/slices/take_slice/39 |
73 | | * New syntax for low-level database record create/update/delete: http://groups.google.com/group/web2py/browse_thread/thread/d79a6e52824d4221 |
74 | | * Default field values with crud.create(): http://groups.google.com/group/web2py/browse_thread/thread/717e2349f0f8e93d |
75 | | * Edit multiple records at once: http://groups.google.com/group/web2py/browse_thread/thread/401b4c192871194c/a96cc8c7923a8565# |
76 | | * Prevent multiple concurrent logins: http://groups.google.com/group/web2py/browse_thread/thread/4e1c62a0d9255160 |
77 | | * Process uploaded files manually (e.g. to unzip KMZ): http://groups.google.com/group/web2py/browse_thread/thread/63809c06cac3b0d5 |
78 | | * Access DB models from a Python script: http://groups.google.com/group/web2py/browse_thread/thread/147b47069a9c1ea2 |
79 | | * Custom Forms |
80 | | * Debug by setting the return to just a plain dict() (=> can read values of vars in 'request') |
81 | | * Latest code method: http://groups.google.com/group/web2py/browse_thread/thread/1d7c1e31b5f66534 |
82 | | * Suggested workflow for customising HTML: http://groups.google.com/group/web2py/browse_thread/thread/95e571e49b7d77ed/8c998b226f5a0437 |
83 | | * less retyping of code in view using SQLFORM extensions: http://groups.google.com/group/web2py/browse_thread/thread/2d8cc57352d158bd |
84 | | * Simple version: http://groups.google.com/group/web2py/browse_thread/thread/7245cab0df469d5f |
85 | | * Alternate approach: http://www.wellbehavedsystems.co.uk/web2py/examples/ |
86 | | * Helper field2html(): http://groups.google.com/group/web2py/browse_thread/thread/1012c11c977aa05e |
87 | | * Multiple per page: http://groups.google.com/group/web2py/browse_thread/thread/57e452d186d48fa4 |
88 | | * Values retrieved from DB are stored for re-referencing: http://mdp.cti.depaul.edu/AlterEgo/default/show/205 |
89 | | * Summary of MVC options: http://groups.google.com/group/web2py/browse_thread/thread/7da38e0d32d01076 |
90 | | * form.accepts AJAX submission: http://groups.google.com/group/web2py/browse_thread/thread/e583a1e377cc7dea |
91 | | * Lambda tricks: http://p-nand-q.com/python/stupid_lambda_tricks.html |
92 | | * THIS_NOT_IN_DB custom validator: http://groups.google.com/group/web2py/browse_thread/thread/27b14433976c0540?pli=1 |
93 | | * IS_IN_DB (...,order_by=...): http://groups.google.com/group/web2py/browse_thread/thread/5fe6e343d115590d/2a8c38fccb2cf3cf#2a8c38fccb2cf3cf |
94 | | * Multiple field validation example: |
| 52 | * [wiki:Web2pyInternalsAndTips Web2py Internals and Tips] |
| 53 | * http://web2py.com/examples/default/docs |
| 54 | * Prevent HTML tags being escaped in views: {{{{{=XML("<p>Not escaped!</p>")}}}}} |
| 55 | * HTML Helpers: http://web2py.com/AlterEgo/default/show/217 |
| 56 | * Arbitrary HTML tags using TAG, e.g. TAG.LEGEND('a','b',_c='d') |
| 57 | * HTML Helpers can be navigated/manipulated like the DOM: http://groups.google.com/group/web2py/browse_thread/thread/ac045f3b1d3846d9 |
| 58 | * https://web2py.com/web2py_wiki/default/wiki/tips |
| 59 | * https://web2py.com/web2py_wiki/default/wiki/widgets |
| 60 | * Pagination: |
| 61 | * Basic server-side pagination: http://web2py.com/AlterEgo/default/show/95 |
| 62 | * Grid to replace SQLTABLE with server-side pagination included: http://www.web2pyslices.com/main/slices/take_slice/39 |
| 63 | * New syntax for low-level database record create/update/delete: http://groups.google.com/group/web2py/browse_thread/thread/d79a6e52824d4221 |
| 64 | * Default field values with crud.create(): http://groups.google.com/group/web2py/browse_thread/thread/717e2349f0f8e93d |
| 65 | * Edit multiple records at once: http://groups.google.com/group/web2py/browse_thread/thread/401b4c192871194c/a96cc8c7923a8565# |
| 66 | * Prevent multiple concurrent logins: http://groups.google.com/group/web2py/browse_thread/thread/4e1c62a0d9255160 |
| 67 | * Process uploaded files manually (e.g. to unzip KMZ): http://groups.google.com/group/web2py/browse_thread/thread/63809c06cac3b0d5 |
| 68 | * Access DB models from a Python script: http://groups.google.com/group/web2py/browse_thread/thread/147b47069a9c1ea2 |
| 69 | * Custom Forms |
| 70 | * Debug by setting the return to just a plain dict() (=> can read values of vars in 'request') |
| 71 | * Latest code method: http://groups.google.com/group/web2py/browse_thread/thread/1d7c1e31b5f66534 |
| 72 | * Suggested workflow for customising HTML: http://groups.google.com/group/web2py/browse_thread/thread/95e571e49b7d77ed/8c998b226f5a0437 |
| 73 | * less retyping of code in view using SQLFORM extensions: http://groups.google.com/group/web2py/browse_thread/thread/2d8cc57352d158bd |
| 74 | * Simple version: http://groups.google.com/group/web2py/browse_thread/thread/7245cab0df469d5f |
| 75 | * Alternate approach: http://www.wellbehavedsystems.co.uk/web2py/examples/ |
| 76 | * Helper field2html(): http://groups.google.com/group/web2py/browse_thread/thread/1012c11c977aa05e |
| 77 | * Multiple per page: http://groups.google.com/group/web2py/browse_thread/thread/57e452d186d48fa4 |
| 78 | * Values retrieved from DB are stored for re-referencing: http://mdp.cti.depaul.edu/AlterEgo/default/show/205 |
| 79 | * Summary of MVC options: http://groups.google.com/group/web2py/browse_thread/thread/7da38e0d32d01076 |
| 80 | * form.accepts AJAX submission: http://groups.google.com/group/web2py/browse_thread/thread/e583a1e377cc7dea |
| 81 | * Lambda tricks: http://p-nand-q.com/python/stupid_lambda_tricks.html |
| 82 | * THIS_NOT_IN_DB custom validator: http://groups.google.com/group/web2py/browse_thread/thread/27b14433976c0540?pli=1 |
| 83 | * IS_IN_DB (...,order_by=...): http://groups.google.com/group/web2py/browse_thread/thread/5fe6e343d115590d/2a8c38fccb2cf3cf#2a8c38fccb2cf3cf |
| 84 | * Multiple field validation example: |
98 | | * CGI co-existence: http://groups.google.com/group/web2py/browse_thread/thread/1520b84d144f0b0c |
99 | | * Inline Images in T2 CRUD: http://groups.google.com/group/web2py/browse_thread/thread/d954bf883baf7adc/3b55a819b425a741 |
100 | | * PIL to create thumbnails: |
101 | | * http://groups.google.com/group/web2py/browse_thread/thread/3523f9a12edc6836 |
102 | | * http://groups.google.com/group/web2py/browse_thread/thread/380cfb61a1fa1596 |
103 | | * Download Images with original filename: |
104 | | * http://groups.google.com/group/web2py/browse_thread/thread/484a2d04bdd7606f |
105 | | * http://groups.google.com/group/web2py/browse_thread/thread/1df80dbf52d401fb |
106 | | * TEXTAREA options: http://groups.google.com/group/web2py/browse_thread/thread/482ecab0878689d5 |
107 | | * nicEdit integration: http://groups.google.com/group/web2py/msg/ff491af9382f6c39 |
108 | | * Multi-column unique constraint: http://groups.google.com/group/web2py/browse_thread/thread/f5ab94cc7d511e0b |
109 | | * Modified preorder Tree Traversal (for large Hierarchical trees): http://groups.google.com/group/web2py/browse_thread/thread/70efddab62dfe73 |
110 | | * Hierarchical References: http://groups.google.com/group/web2py/browse_thread/thread/a4f57635d4a05f83 |
111 | | * JSON datetime serialization: https://web2py.com/web2py_wiki/default/wiki/JSONdatetime |
112 | | * Enter key in ajaxified forms: http://groups.google.com/group/web2py/browse_thread/thread/bae7b19ff35b896b# |
113 | | * Limiting access to a controller function to just certain IPs: http://groups.google.com/group/web2py/msg/df000860c707d3d3 |
114 | | * Auto-complete (for when Dropdowns get too long): |
115 | | * AutoComplete guidelines proposal |
116 | | * use the [wiki:ajaxS3 ajaxS3] calls: ''getS3'', ''getJSONS3'', or ''postS3'' |
117 | | * use the [wiki:IS_ONE_OF_EMPTY IS_ONE_OF_EMPTY] validator |
118 | | * http://trac.sahanapy.org/browser/views/msg/email_outbox_create.html |
119 | | * http://groups.google.com/group/web2py/browse_thread/thread/e1034df0091b5bfd |
120 | | * http://groups.google.com/group/web2py/browse_thread/thread/f6e0170273b14241 |
121 | | * http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/ (Also: http://plugins.jquery.com/project/autocompletex) |
122 | | * http://dyve.net/jquery/?autocomplete (Older version: http://www.pengoworks.com/workshop/jquery/autocomplete.htm) |
123 | | * http://code.google.com/p/js-autocomplete/ |
124 | | * http://github.com/ReinH/jquery-autocomplete/tree/master (Also: http://plugins.jquery.com/project/jq-autocomplete) |
125 | | * http://plugins.jquery.com/project/YA_AutoComplete |
126 | | * EPB: http://groups.google.com/group/web2py/browse_thread/thread/c090560680b65db2 |
127 | | * Implementing Plone's Indexing & Workflow: http://groups.google.com/group/web2py/browse_thread/thread/496edd88f6298653 |
128 | | * Importing Legacy Data: http://groups.google.com/group/web2py/browse_thread/thread/5bd8f85b21444858 |
129 | | * Upload progress: http://www.web2pyslices.com/main/slices/take_slice/10 |
130 | | * Use the StatusBar for dynamic status updates |
131 | | * http://code.google.com/p/web2pyorm/ |
| 88 | * CGI co-existence: http://groups.google.com/group/web2py/browse_thread/thread/1520b84d144f0b0c |
| 89 | * Inline Images in T2 CRUD: http://groups.google.com/group/web2py/browse_thread/thread/d954bf883baf7adc/3b55a819b425a741 |
| 90 | * PIL to create thumbnails: |
| 91 | * http://groups.google.com/group/web2py/browse_thread/thread/3523f9a12edc6836 |
| 92 | * http://groups.google.com/group/web2py/browse_thread/thread/380cfb61a1fa1596 |
| 93 | * Download Images with original filename: |
| 94 | * http://groups.google.com/group/web2py/browse_thread/thread/484a2d04bdd7606f |
| 95 | * http://groups.google.com/group/web2py/browse_thread/thread/1df80dbf52d401fb |
| 96 | * TEXTAREA options: http://groups.google.com/group/web2py/browse_thread/thread/482ecab0878689d5 |
| 97 | * nicEdit integration: http://groups.google.com/group/web2py/msg/ff491af9382f6c39 |
| 98 | * Multi-column unique constraint: http://groups.google.com/group/web2py/browse_thread/thread/f5ab94cc7d511e0b |
| 99 | * Modified preorder Tree Traversal (for large Hierarchical trees): http://groups.google.com/group/web2py/browse_thread/thread/70efddab62dfe73 |
| 100 | * Hierarchical References: http://groups.google.com/group/web2py/browse_thread/thread/a4f57635d4a05f83 |
| 101 | * JSON datetime serialization: https://web2py.com/web2py_wiki/default/wiki/JSONdatetime |
| 102 | * Enter key in ajaxified forms: http://groups.google.com/group/web2py/browse_thread/thread/bae7b19ff35b896b# |
| 103 | * Limiting access to a controller function to just certain IPs: http://groups.google.com/group/web2py/msg/df000860c707d3d3 |
| 104 | * Auto-complete (for when Dropdowns get too long): |
| 105 | * AutoComplete guidelines proposal |
| 106 | * use the [wiki:ajaxS3 ajaxS3] calls: ''getS3'', ''getJSONS3'', or ''postS3'' |
| 107 | * use the [wiki:IS_ONE_OF_EMPTY IS_ONE_OF_EMPTY] validator |
| 108 | * http://trac.sahanapy.org/browser/views/msg/email_outbox_create.html |
| 109 | * http://groups.google.com/group/web2py/browse_thread/thread/e1034df0091b5bfd |
| 110 | * http://groups.google.com/group/web2py/browse_thread/thread/f6e0170273b14241 |
| 111 | * http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/ (Also: http://plugins.jquery.com/project/autocompletex) |
| 112 | * http://dyve.net/jquery/?autocomplete (Older version: http://www.pengoworks.com/workshop/jquery/autocomplete.htm) |
| 113 | * http://code.google.com/p/js-autocomplete/ |
| 114 | * http://github.com/ReinH/jquery-autocomplete/tree/master (Also: http://plugins.jquery.com/project/jq-autocomplete) |
| 115 | * http://plugins.jquery.com/project/YA_AutoComplete |
| 116 | * EPB: http://groups.google.com/group/web2py/browse_thread/thread/c090560680b65db2 |
| 117 | * Implementing Plone's Indexing & Workflow: http://groups.google.com/group/web2py/browse_thread/thread/496edd88f6298653 |
| 118 | * Importing Legacy Data: http://groups.google.com/group/web2py/browse_thread/thread/5bd8f85b21444858 |
| 119 | * Upload progress: http://www.web2pyslices.com/main/slices/take_slice/10 |
| 120 | * Use the StatusBar for dynamic status updates |
| 121 | * http://code.google.com/p/web2pyorm/ |
| 122 | |
| 123 | == CSS & Javascript debugging == |
| 124 | * use Firebug: http://code.google.com/support/bin/answer.py?answer=77412&topic=12044 |
| 125 | * use [http://www.sprymedia.co.uk/article/Visual+Event Visual Event] to see which events are active. |
| 126 | * use Venkman: http://www.mozilla.org/projects/venkman/ |
| 127 | * use Fiddler for compressed files: http://www.yuiblog.com/blog/2008/06/27/fiddler |
| 128 | * http://pastebin.me (allows edits of HTML & previews) |
| 129 | * http://jsfiddle.net (allows edits of JS & previews) |
| 130 | * http://yura.thinkweb2.com/domlint/ |
| 131 | * http://www.jslint.com/lint.html |
| 132 | * IE6 cheatsheet: http://www.virtuosimedia.com/tutorials/ultimate-ie6-cheatsheet-how-to-fix-25-internet-explorer-6-bugs |
134 | | * http://trac.openlayers.org/wiki/Documentation#BeforeGettingStarted--TheTechnologiesBehindOpenLayers |
135 | | * http://eloquentjavascript.net |
136 | | * Dynamically load additional JS: http://unixpapa.com/js/dyna.html |
137 | | * [http://aymanh.com/9-javascript-tips-you-may-not-know#String_Concatenation_vs._Array.join array.join instead of string concatenation] (& other tips) |
138 | | * Ensure variable names use only Word characters: |
139 | | * Python: {{{variable_name = re.sub('\W', '_', string)}}} |
140 | | * JS: {{{var RE_JSVAR = new RegExp("\W", "g"); var variable_name = string.replace(RE_JSVAR, '_');}}} |
141 | | * Loop timings: http://blogs.sun.com/greimer/entry/best_way_to_code_a |
142 | | * Closures: http://www.javascriptkit.com/javatutors/closures.shtml |
143 | | * Memory Leaks: http://www.javascriptkit.com/javatutors/closuresleak/index.shtml |
| 135 | * http://trac.openlayers.org/wiki/Documentation#BeforeGettingStarted--TheTechnologiesBehindOpenLayers |
| 136 | * http://eloquentjavascript.net |
| 137 | * Dynamically load additional JS: http://unixpapa.com/js/dyna.html |
| 138 | * [http://aymanh.com/9-javascript-tips-you-may-not-know#String_Concatenation_vs._Array.join array.join instead of string concatenation] (& other tips) |
| 139 | * Ensure variable names use only Word characters: |
| 140 | * Python: {{{variable_name = re.sub('\W', '_', string)}}} |
| 141 | * JS: {{{var RE_JSVAR = new RegExp("\W", "g"); var variable_name = string.replace(RE_JSVAR, '_');}}} |
| 142 | * Loop timings: http://blogs.sun.com/greimer/entry/best_way_to_code_a |
| 143 | * Closures: http://www.javascriptkit.com/javatutors/closures.shtml |
| 144 | * Memory Leaks: http://www.javascriptkit.com/javatutors/closuresleak/index.shtml |
| 145 | |
145 | | * http://www.smashingmagazine.com/2008/09/16/jquery-examples-and-best-practices/ |
146 | | * http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx |
147 | | * http://james.padolsey.com/javascript/things-you-may-not-know-about-jquery/ |
148 | | * http://15daysofjquery.com/ |
149 | | * http://jqueryfordesigners.com/jquery-tabs/ |
150 | | * http://devsnippets.com/reviews/using-jquery-to-style-design-elements-20-impressive-plugins.html |
151 | | * http://www.mapbender.org/JavaScript_pitfalls:_null,_false,_undefined,_NaN |
152 | | * http://www.learningjquery.com/2009/03/43439-reasons-to-use-append-correctly |
153 | | * Web2Py HTML Helper: http://groups.google.com/group/web2py/browse_thread/thread/ec63ee9af3ee659f |
154 | | * jqGrid in Web2Py: http://groups.google.com/group/web2py/browse_thread/thread/2caa0e4e0161bb8d |
| 147 | * http://www.smashingmagazine.com/2008/09/16/jquery-examples-and-best-practices/ |
| 148 | * http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx |
| 149 | * http://james.padolsey.com/javascript/things-you-may-not-know-about-jquery/ |
| 150 | * http://15daysofjquery.com/ |
| 151 | * http://jqueryfordesigners.com/jquery-tabs/ |
| 152 | * http://devsnippets.com/reviews/using-jquery-to-style-design-elements-20-impressive-plugins.html |
| 153 | * http://www.mapbender.org/JavaScript_pitfalls:_null,_false,_undefined,_NaN |
| 154 | * http://www.learningjquery.com/2009/03/43439-reasons-to-use-append-correctly |
| 155 | * Web2Py HTML Helper: http://groups.google.com/group/web2py/browse_thread/thread/ec63ee9af3ee659f |
| 156 | * jqGrid in Web2Py: http://groups.google.com/group/web2py/browse_thread/thread/2caa0e4e0161bb8d |
166 | | * http://enhance.qd-creative.co.uk/2008/06/28/the-misunderstood-div/ |
167 | | * http://enhance.qd-creative.co.uk/2008/10/14/7-things-you-can-do-so-your-users-wont-leave/ |
168 | | * Usability: http://www.useit.com |
169 | | * Progressive Enhancement (better than Graceful Degradation): |
170 | | * http://developer.yahoo.com/yui/articles/gbs/ |
171 | | * http://accessites.org/site/2007/02/graceful-degradation-progressive-enhancement/ |
172 | | * http://www.alistapart.com/articles/understandingprogressiveenhancement |
173 | | * http://www.alistapart.com/articles/progressiveenhancementwithcss |
174 | | * http://www.alistapart.com/articles/progressiveenhancementwithjavascript |
175 | | * http://webtips.dan.info/graceful.html |
| 168 | * http://enhance.qd-creative.co.uk/2008/06/28/the-misunderstood-div/ |
| 169 | * http://enhance.qd-creative.co.uk/2008/10/14/7-things-you-can-do-so-your-users-wont-leave/ |
| 170 | * Usability: http://www.useit.com |
| 171 | * Progressive Enhancement (better than Graceful Degradation): |
| 172 | * http://developer.yahoo.com/yui/articles/gbs/ |
| 173 | * http://accessites.org/site/2007/02/graceful-degradation-progressive-enhancement/ |
| 174 | * http://www.alistapart.com/articles/understandingprogressiveenhancement |
| 175 | * http://www.alistapart.com/articles/progressiveenhancementwithcss |
| 176 | * http://www.alistapart.com/articles/progressiveenhancementwithjavascript |
| 177 | * http://webtips.dan.info/graceful.html |