Wednesday, February 18, 2009

My Drupal Note

- 在 index.php 最上面擺
error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);


- Debug functions
dpm() prints a simple variable
dvm prints a var_dump()
dpr() prints a complex variable at the top of a page using a special recursive function (dprint_r()) that gives nicely formatted output
dvr() prints a nicely formatted var_dump() to the top of the page

Quick Note:
- Find out how come hook_menu() 遇到 %user_uid_optional 時 (or more than certain 段),它的 breadcrumb 就斷掉了? (還是有辦法弄回來,只是要有點 trick [有關 menu parent/child 的排列, 還有 MENU_NORMAL_ITEM, MENU_CALLBACK 好像也有關係?],覺得麻煩的話,直接用 drupal_set_breadcrumb() 吧

- 把 select content type 的 sql statement 寫成 function. companygossip_page_user()

- Hook_View()
- Hook_Load()
- Hook_nodeapi()

- 查 node / node type / term 之間的關係

- 如果 breadcrumb / Navigation 有問題時,
- 觀察 nai_menu_links table,
- 以及 menu.inc 的 array_pop($breadcrumb);
- 還有 兩層時 %user/% 會怪怪的,第二層用 MENU_DEFAULT_LOCAL_TASK ?

- Nainews.module 的 id_comp (and count ceo msg) 的問題還沒有解決!

- 如果 menu 的 page arguments

- The callback arguments you define in page arguments will be passed to the callback function BEFORE (that is, placed first in the list of parameter values that are passed to the callback) any arguments generated from the path. The arguments from the URL are still available; to access them, you would change the function signature of your callback to add parameters from the URL. P. 66.

Keys in keyed arrays are ignored in page callback argumnets, so you can't use keys to map to function parameters; only order is important. P. 66.

- off-site links:
- http://stevelockwood.net/index.php?q=cms
-

- 要研究的幾個 function
pager_query // query db related

db_rewrite_sql // query db related

variable_get // 從 database 裡的 table 調 value.

l // You can add additional values, such as 'class', in the array to customize the link.

t // Translate to human readble

check_plain // The solution is to use an appropriate filter when needed. For example, just before sending plain text to the browser or mixing plain text with HTML, escape it with check_plain.

drupal_get_form // function handles retrieving, processing, and displaying a rendered HTML form for modules automatically.
// Note that the form builder function always takes $form_state as its first argument

drupal_execute // Forms can also be built and submitted programmatically without any user input using the drupal_execute() function.

module_invoke // To call another block within inside another block.
// Sample:
// $block = module_invoke('nainews', 'hookName', 'arg0', 'arg1');
// print $block['content'];

module_invoke_all // If you are interested in seeing the function taht drives the hook mechanism, see the module_invoke_all() function in includes/module.inc.

module_implements //

drupal_goto // similiar to $form['#redirect'] or $form_state['redirect']

url //

drupal_set_message // Set a message which reflects the status of the performed operation.

// Call a function from another module.
// The module_exists() function is a Drupal API call that tells you if a module is enabled. function_exists() is a PHP function that tells you if the function is defined and available to you.
// Of course, if the other module is not enabled you should handle accordingly. But there exists a method in teh .info file to specify dependancy on other modules.
// Note: the correct one is just the functionName().
// Or try http://drupal.org/handbook/customization/php-snippets
if (module_exists('module_name') && function_exists('module_name_function_name')) {
module_name_function_name();
}

drupal_set_content // Content can be manually set inside regions with drupal_set_content
// http://drupal.org/node/171224

arg // Get parameters in url
// http://api.drupal.org/api/function/arg/6

file_create_url // Create the download path to a file.

theme('image', 'sites/all/themes/acquia_marina/icons/ceo.gif', $alt, $alt, '', FALSE) // show display image.

profile_load_profile // can be used to load profile fields.

module_implements // Determine which modules are implementing a hook.

node_invoke // Invoke a node hook.

node_invoke_nodeapi // Invoke a hook_nodeapi() operation in all modules.


- 建議要裝的 module
- devel.module // For Development Debugging. There are more useful functions in this module.

- Firebug (Firfox Extension / Add-on)

- CCK
- date.module
- views.module
- Calendar.module
- flag.module
- Advanced_help.module // The advanced help module allows module developers to store their help outside the module system, in pure .html files. The files can be easily translated simply by copying them into the right translations directory. The entire system can appear in a popup or not as the module prefers (and by taking away access to view the popups, a site can force the popups to not exist).

- Captcha: prevent spam, but don't set it too difficult !

- Panels

- Mailing List
- *** Simplenews
- Mailman Manager

- Groups / Forums
- Organic groups

- Rating (投票/按好/push)
- NodeReview.module
- Suggested link
- *** FiveStar

- FCKeditor // WYSIWYG HTML editor

- Navigation / Breadcrumbs
- Custom Breadcrumbs (with token.module)
- Node breadcrumbs
- Taxonomy Breadcrumb

- schema // Schema documentation: hyperlinked display of the schema's embedded documentation explaining what each table and field is for.

- 建議要裝的 theme
- Zen
- Acquia Marina
- Advanced Theme Construction Kit (ATCK)

- 幾個可以 study 一下的 module
- built-in search.module
- announcements.module // Great. block, hook, theme, and more.
- currency.module // Retrieve data from other sites.
- calendar_block.module // study cache.

- 幾個重要的 topic
- Drupal API
http://api.drupal.org/

- Module
- Module HowTos
http://drupal.org/node/22573

- How to update a module's weight
http://drupal.org/node/110238

- Block
- The appearance of a block is controlled in a theme by the (code: block($subject, $content, $region = "main") method.
http://drupal.org/getting-started/before/terminology
http://drupal.org/node/17170

- Block: controlling content in the sidebars
http://drupal.org/handbook/modules/block

- Hook
- hook_menu
http://api.drupal.org/api/function/hook_menu/6

- *** Menu
Define the navigation menus, and route page requests to code based on URLs.

The Drupal menu system drives both the navigation system from a user perspective and the callback system that Drupal uses to respond to URLs passed from the browser. For this reason, a good understanding of the menu system is fundamental to the creation of complex modules.

http://api.drupal.org/api/group/menu/6
// 有講解一些 array 裡的 elements 的 definition 和 用法
http://api.drupal.org/api/function/hook_menu/6
// arg( )
http://api.drupal.org/api/function/arg/6
http://api.drupal.org/api/file/developer/examples/page_example.module/6 (點選 view source,詳讀 hook_menu() )

- Menu.inc
http://api.drupal.org/api/file/includes/menu.inc/6/source

- Wildcard usage and core's wildcards
http://drupal.org/node/209056

- *** Dynamic argument replacement (wildcard)
http://drupal.org/node/109153

- Wildcard Loader Arguments
http://drupal.org/node/224170

- Form
- Form generation
http://api.drupal.org/api/group/form_api/6

- Forms API Quickstart Guide
http://api.drupal.org/api/file/developer/topics/forms_api.html/6

- forms_api_reference.html
http://api.drupal.org/api/file/developer/topics/forms_api_reference.html/6



- Views
- The Views module provides a flexible method to control how lists of posts are retrieved and presented.

See the Views Module Developer API for detailed instructions on how to expose your module's tables and fields to views operations.
http://drupal.org/handbook/modules/views/api

- Why use Views? Why not write your own queries?
http://drupal.org/node/242311

- Managing views in code
http://drupal.org/node/272912

- Theme
- ***** Using the theme layer (Drupal 6.x)
http://drupal.org/node/165706

- If you are developing a module that outputs presentation data, then please read the module developer's guide Using the theme layer section.
http://drupal.org/node/165706

- Default theme implementations
http://api.drupal.org/api/group/themeable/6

- theme
http://api.drupal.org/api/function/theme/6

- hook_theme
http://api.drupal.org/api/function/hook_theme/6

- How to write themable modules
http://drupal.org/node/306

- About theming
http://drupal.org/node/221881

- Drupal 6 theme guide
http://drupal.org/theme-guide/6

- Tools, best practices and conventions
http://drupal.org/node/341707

- HTML and CSS techniques and tools
http://drupal.org/node/37156

- There are two ways to provide a default implementation. The easier but less recommend way is to provide a function, and the recommended way is to provide a template and a corresponding preprocessor function.

- *** Assigning content to regions
http://drupal.org/node/171224

- *** Setting up variables for use in a template (preprocess functions)
http://drupal.org/node/223430

- ***** About overriding themable output
http://drupal.org/node/173880

- *** Theme developer module for Drupal 6 - Screencast
http://drupal.org/node/209561

- Regions in themes (Drupal 4, 5)
http://drupal.org/node/29140

- Totally customize the LOOK of your front page
http://drupal.org/node/317461

- Core templates and suggestions
http://drupal.org/node/190815#template-suggestions

- Structure of the .info file
http://drupal.org/node/171205#regions

- Action
http://drupal.org/node/172152

- Database
- Database abstraction layer
http://api.drupal.org/api/group/database

- How to write database independent code
http://drupal.org/node/1395

- How to write efficient database JOINs
http://drupal.org/node/2041

- So, once more; There are three kind of errors you need to avoid: XSS with proper checking, SQL injections with proper db_query usage and node access bypass by utilizing db_rewrite_sql.

- When to use db_rewrite_sql

db_rewrite_sql() provides a method for modules to extend your SQL queries. This kind of functionality is especially important to modules which control access to nodes.
http://drupal.org/node/93737

- Others
- How to use watchdog() in your own code
http://drupal.org/node/86124

- How to measure the execution time of your Drupal scripts
http://drupal.org/node/320208

- How to make tablesorting work with multiple tables on the same page
http://drupal.org/node/98097

- Updating your modules
http://drupal.org/update/modules

- Tools, tips and tricks
http://drupal.org/node/188989

- Main content-related hooks
http://drupal.org/node/112180

- 'Status' field values for nodes and comments
http://drupal.org/node/4739

- Why does Drupal filter on output?
http://drupal.org/node/263002

- A beginner's guide to using PHP snippets
http://drupal.org/node/337959

- PHP snippets
http://drupal.org/handbook/customization/php-snippets

- Creating, displaying and combining content
http://drupal.org/node/206673

- Slashes in URL's instead of PHP parameters
http://drupal.org/node/1650

-

Must read:

Form:
http://api.drupal.org/api/file/developer/topics/forms_api.html
http://api.drupal.org/api/file/developer/topics/forms_api_reference.html

Writing Secure Code:
http://drupal.org/writing-secure-code

Coding standards:
http://drupal.org/node/318

- 一個 module 的 permissions 不能隨便改!它是把 string 寫到 database 的
Your permission strings are arbitrary, but each must be unique among all installed modules. Otherwise, one occurrence of the name will take the permissions of the other. The permission strings should each usually contain your module name, since this helps avoid name space conflicts with other modules.

- drupal 是利用透過 網址上的 slash 來當做 hook_functions( ) 的 argument (parameter)

- Another very important point to note: we are dealing with nodes and the node access mechanism kicks in via db_rewrite_sql so we are utilizing it. It's really easy and yet it's so often neglected! See When to use db_rewrite_sql for further details.
http://drupal.org/node/93737

So, once more; There are three kind of errors you need to avoid: XSS with proper checking, SQL injections with proper db_query usage and node access bypass by utilizing db_rewrite_sql.

- Inline documentation for source files should follow the Doxygen formatting conventions.
http://drupal.org/node/1354

- Note that as of Drupal 4.7, the ?> at the end of code files is purposely omitted. This includes for module and include files. The reasons for this can be summarized as:

Removing it eliminates the possibility for unwanted whitespace at the end of files which can cause "header already sent" errors, XHTML/XML validation issues, and other problems.
The closing delimiter at the end of a file is optional.
PHP.net itself removes the closing delimiter from the end of its files
(example: prepend.inc), so this can be seen as a "best practice."

- two time-related functions:
strtotime( )
mktime( )

- Share a single database across multiple sites
http://drupal.org/node/2622

- Define shared variables for all sites
http://drupal.org/node/70472

- We use variable_get( ) to retrieve the value of the system configuration variable "onthisdate_maxdisp", and define the default value to be

look at the "variable" table in database

http://drupal.org/node/206761

Forms API Quickstart Guide
*** http://api.drupal.org/api/file/developer/topics/forms_api.html/6

- drupal_get_form( ) does the following:

* Starts the entire form-building process by getting the $form from the builder function
* Translates the $form['name'] items into actual form elements
* Performs any validation and "clean-up" that needs to be done, and calls custom validation functions if declared
* Submits the form if a submit function is declared, and the form has been submitted
* Calls any custom theming functions that have been declared
* Returns an HTML string which contains the actual form.

For more detailed information, also see the API page for drupal_get_form()

- An important thing to note: notice that $form['access'] has a '#tree' => TRUE attribute. this setting retains the full tree structure for all elements under it when it is passed to $form_state['values']. you must explicitly declare this anywhere you wish to retain an array's full hierarchy when it is passed.

- Use CCK (Content Construction Kit). This module allows you to create custom content types, containing all sorts of fields: text, numbers, image upload, node reference. For categorization, use the core module called taxonomy (find it at /admin/content/taxonomy).

- Drupal menu system
http://drupal.org/node/102338

- hook_menu( ) 是重點!
感覺一個 module 以 hook_menu( ) 為核心,根據在 hook_menu( ) 裡所定義的設定,去呼叫要做哪些事。

Contrary to all our other functions, 'all' and 'admin' (from the previous tutorial), are not Drupal hooks.

If you want to call this function from another module, use the standard naming scheme we've been using: modulename_action. It can be called using the function module_invoke function. If you want the function to remain private (because, say, it's merely a helper function in your module) and easily accessible by only your module, prefix the function name with an underscore.

- Drupal 的設計思想之一,跟 URL 所傳來的 parameters 有很大的關聯,並且還以 forward-Slash 分別代表 calling a function 的 parameters,例如 http://MyDomain/?q=MyModuleName/MyFirstName/MyLastName 那麼,假設今天我們 access 該 URL,該 URL 接著 call 一個我們所定義的 function,例如 MyModuleName_showAllContent ,那麼 MyModuleName_showAllContent( $firstName, $lastName ) function 可以以它的 parameter 來接收 URL 所傳來的值。

- 有不同的 theme when viewing different modules

- theme 的多格編排方式

- menu_router( ) table stores block access permissions and more!

- 在 function name 前加 底線 表示 a private function

- *** Must Read All - Terminology 術語
http://drupal.org/node/937

- How to troubleshoot (read this first)

Try the devel.module
http://drupal.org/node/72108

- Views is your friend. It allows you to filter the nodes you need, specify the fields you want to display and choose how to publish it.

- As mentioned previously, the function we just wrote isn't a 'hook': it's not a Drupal recognized name. We need to tell Drupal how to access the function when displaying a page. We do this with Drupal's hook_menu. Remember that we have already used hook_menu in the seventh tutorial in this series. The hook_menu defines the association between a URL and the function that creates the content for that url. The hook also does permission checking, if desired. We will use the hook_menu made previously and continue with it.

http://drupal.org/node/206764

- Drupal Programming from an Object-Oriented Perspective
http://api.drupal.org/api/file/developer/topics/oop.html/6

- String translation is mandatory; use it and love it
- String Accessibility
- String Security
http://drupal.org/node/299085

- UI (Theme) elements in Drupal 6
http://drupal.org/node/366887

- Doxygen formatting conventions
Drupal uses Doxygen to automatically generate documentation from the latest Drupal sources
http://drupal.org/node/1354

- navigation = breadcrumb

- showcase / case study / website

- Scalability options
For large sites, Drupal 6 performs properly when running behind a reverse proxy like Squid or Pound.

- Enabling user pictures / member picture / user photo / member photo / user avatars / member avatars

Note:
對於不同使用需求的 Drupal 入門玩家,你會給些什麼建議?

1. 架網站前,與其去了解 Drupal,不如先去思考架的網站類型(Portal, Forum, Blog, ...)有哪些類型的內容。這時完全不要去理會版型、網站呈現、配色或任何其它會把你注意力放到「畫面」的事務上,只要專心在內容的類型與分類,還有他們之間的關係就行。這絕對會花上好一段時間,而且花上一個禮拜或一個月都是正常的。
2. 對於入門 Drupal 的玩家來說,首要任務是了解 Node, Taxonomy, Menu 與 Block 這四個 Drupal 核心就「宅配」的模組。他們分別處理了「內容」「分類」「導覽式選單」「各式各樣組織過的區塊」。
3. 假設你作到了前兩點,那你可以開始使用 CCK 搭配 Views,把你之前提畫的內容類型,一一實現出來,而且重點是,只需要透過決定欄位,打打幾個欄位名稱與說明,然後用滑鼠點一點就行了,一丁點兒都不需要去寫什麼程式才對。對了,再次聲明,還是不需要在這個階段理會版型。
4. 再次回來認真看待 Views,這時你得開始用 Views 產生你要的 Page View(或 Block View),然後 key 一些資料進去,看看產生的 views 正不正常。我實在很想強調,一個使用 Drupal 架的網站,只要好好搞定 CCK 與 Views,你就可以不用再回來操心這類與「資料」有關的事了。
5. 插曲:為了讓你 key 資料方便些,你可以安裝一些 TinyMCE, FCKEditor(我最愛的), BBUEditor, ... 很多。可以在 http://drupal.org/project/Modules/category/63 找到你需要的。
6. 如果你一開始要架設的網站,屬於個人性質的,那接下來就是先去套用幾個你愛的版型(theme),然後就好了。真的,你現在最最需要的就是堆資料了,在沒有夠份量內容前,做再多都是白費力氣。

最後,一些很實用的模組的推薦列表:

* Drupal Podcast No. 40: Top 40 Projects
* 10 must have Drupal Modules
* Most Downloaded Drupal Modules
* Drupal Projects usage
http://drupaltaiwan.org/forum/20081110/2768

No comments: