سفارشی سازی صفحه‌ی ایجاد محتوا در دروپال

صفحه‌ی ایجاد محتوا در دروپال (یعنی صفحه‌ی node/add) جلوه‌‌ی چندان جذابی ندارد. در زیر تصویر صفحه‌ی ایجاد محتوا را به شکل پیش‌فرض آن در دروپال 6 مشاهده می‌کنید.

صفحه‌ی ایجاد محتوا در دروپال به صورت پیش فرض و بدون سفارشی‌سازی چندان جذاب به نظ

به خصوص هنگامی که دروپال را برای یک مشتری بخواهیم نصب کنیم، زیاد جالب و مناسب نیست. برای حل این مشکل، نیز مانند مشکلات دیگر، دروپال همواره راه حلی درخور و مناسب ارائه می‌دهد.

در این مقاله قصد دارم روش بهینه سازی و زیبا سازی این صفحه را برای شما توضیح دهم.

این مقاله را هنگامی نوشتم که داشتم صفحه‌ی ایجاد محتوا را برای همین وبلاگ خودم (www.hejazee.com) سفارشی می‌کردم. زیرا تعداد Content type های موجود در این سایت زیاد می‌باشد. و لذا برای تفنن، این ایده را عملی کردم!

نتیجه‌ی کار ما در این مقاله، چیزی شبیه تصویر زیر خواهد بود:

صفحه‌ی ایجاد محتوا در دروپال اگر سفارشی سازی شود، می‌تواند بسیار زیباتر شود.

پیش از هر چیز باید بگویم که سفارشی سازی صفحات در دروپال در 99 درصد مواقع باید توسط پوسته انجام گیرد. و لذا این مقاله نیز مستثنی نیست و ما تلاش خواهیم کرد که پوسته‌مان را تغییر دهیم. و البته توضیحات ارائه شده در این قسمت ممکن است برای پوسته‌های مختلف، اندکی تفاوت داشته باشد، اما مطمئنا تفاوت عمده ای وجود نخواهد داشت.

نکته‌ی دیگر این که این روش برای دروپال 6 نوشته شده است و البته گمان می کنم که روی دروپال 7 هم کار کند ولی آزمایش نکرده ام. برای اطمینان به API دروپال 7 مراجعه کنید.

روش کار به این صورت است که قبل از هر چیز، باید فایل template.php را در پوسته‌ی سایتتان باز کنید.

نکته اینجاست که هر صفحه‌ای و همچنین هر چیز قابل نمایشی در دروپال، توسط لایه‌ی پوسته (theme layer) نه نمایش گذاشته می‌شود. و همه‌ی کد های HTML خروجی دروپال، توسط پوسته تولید می‌شود.

هر عنصری در دروپال که دارای خروجی HTML باشد، ماژول تولید کننده‌ی آن عنصر، برای تولید خروجی باید از یکی از دو روش زیر استفاده کند:

  1. یک تابع theme برای آن عنصر مذکور تعریف کند. که در این صورت، این تابع توسط توابع پوسته قابل Override کردن خواهد بود.
  2. میتواند یک فایل .tpl.php تعریف کند که آن نیز توسط توابع و فایل های پوسته‌ی فعال قابل Override کردن خواهد بود.

صفحه‌ی ایجاد محتوا (یعنی صفحه‌ی node/add) نیز توسط ماژول node (از ماژول‌های هسته‌ی دروپال) ایجاد شده است و برای تولید خروجی آن هم، یک تابع به نام theme_node_add_list() تعریف کرده است.

بنابراین، ما برای این‌که خروجی این صفحه را تغییر دهیم، باید که تابع فوق را Override کنیم و مکان مناسب برای Override کردن این تابع نیز، فایل template.php در پوسته‌ی مورد نظرمان است.

بنا بر این، فایل template.php را باز کنید. باید تابعی تعریف کنید که می‌تواند هر یک از توابع زیر باشد: (MY_THEME نام پوسته است)

  • MY_THEME_node_add_list()
  • phptemplate_node_add_list()

در صورتی که یکی این توابع قبلا تعریف شده است، مجددا آن را تعریف نکنید.

نکته: تابع اولی اولویت بیشتری برای اجرا شدن دارد. لذا اگر تابع اولی تعریف شود، تابع دوم حتی اگر تعریف شده باشد نیز، استفاده نخواهد شد.

من تابع اولی را استفاده کردم.

توجه مهم: این تابع یک آرگومان به نام $content دریافت می‌کند.

شکل تابع باید شبیه مثال زیر باشد:

/** AHMAD:
 * Override theme_node_add_list()
 * This theme function is called to generate the contents of node/add page
 * 
 * Add node type's class to each list item
 */
function MY_THEME_node_add_list($content) {
  $output = '';
  if ($content) {
    $output = '
'; foreach ($content as $item) { //The node type is not passed to this function, but I can get it from access //argument! which is something like array('create', 'node_type') !! $access_arguments = unserialize($item['access_arguments']); $node_type = $access_arguments[1]; $output .= "
"; $output .= "
"; $output .= "
". l($item['title'], $item['href'], $item['localized_options']) .'
'; $output .= "
". _MY_THEME_word_trim(filter_xss_admin($item['description']), 25, TRUE) .'
'; $output .= "
"; $output .= "
"; } $output .= '
'; } return $output; }

هدف ما از تابع فوق این است که هر نوع محتوایی را در یک div قرار دهیم و یک کلاس به آن اختصاص دهیم. تا به این ترتیب، بتوان کنار هر یک از نوع های محتوا در صفحه‌ی ایجاد محتوا، یک تصویر قرار داد و استایل های متعدد به آن داد.

نکته‎ی قابل ذکر در تابع فوق این است که متغیر $content "نام ماشینی" نوع محتوا را در خود ذخیره نکرده است. لذا من برای بدست آوردن نام ماشینی نوع محتوا یک حقه به کار برده ام :)
به این صورت که از access arguments هر یک از لینک ها استفاده کرده ام. زیرا در access arguments نام ماشینی نوع محتوا وجود دارد (مثلا مجوز ایجاد صفحه، مجوز ایجاد story و ...)

برای به دست آوردن نام نوع محتوا از کد زیر استفاده کرده ام که می بینید:

$access_arguments = unserialize($item['access_arguments']);
$node_type = $access_arguments[1];

سپس همان طور که می‌بینید، دور هر یک از جفت dt و dl دو عدد div قرار داده ام تا بتوانم به آن استایل بدهم.

نکته‌ی دیگری که حائز اهمیت است، این است که توضیحات هر نوع محتوا ممکن است طولانی باشد و در کادر جا نشود. برای این منظور، من از تابع دیگری به نام _MY_THEME_word_trim استفاده کردم.

این تابع، یک رشته را دریافت می کند و آن را کوتاه می‌کند و تحویل می‌دهد. در زیر تعریف آن را می‌بینید:

/**
* Trim a string to a given number of words
*
* @param $string
*   the original string
* @param $count
*   the word count
* @param $ellipsis
*   TRUE to add "..."
*   or use a string to define other character
* @param $node
*   provide the node and we'll set the $node->
*  
* @return
*   trimmed string with ellipsis added if it was truncated
* 
* @see http://www.lullabot.com/articles/trim-a-string-to-a-given-word-count
*/
function _MY_THEME_word_trim($string, $count, $ellipsis = FALSE){
  $words = explode(' ', $string);
  if (count($words) > $count){
    array_splice($words, $count);
    $string = implode(' ', $words);
    if (is_string($ellipsis)){
      $string .= $ellipsis;
    }
    elseif ($ellipsis){
      $string .= '…';
    }
  }
  return $string;
}

پس از این که تغییرات فوق را در فایل template.php ایجاد کردیم، آن را ذخیره می کنیم و theme registry را پاک می کنیم. برای این منظور کافی است به صفحه‌ی Performence یا کارائی بروید و دکمه‌ی Clear All caches را کلیک کنید.

اکنون قسمت اصلی کار انجام شده است. فقط کافی است که قدری استایل CSS ایجاد کنید و صفحه تان را بیارایید. استایلی که می‌نویسید کاملا به خود شما بستگی دارد.

اما استایلی که من به کار بردم چیزی مشابه زیر است:

/**
 * Style the node/add page
 */
dl.node-type-list {
  
}
dl.node-type-list dt {

}
dl.node-type-list dd {
  margin-right: 50px;
}
dl.node-type-list div.node-add-item-inner {
  border: 1px solid transparent;
  border-radius: 3px;
  -moz-border-radius: 3px;
  -webkit-border-radius: 3px;
  -khtml-border-radius: 3px;
  -o-border-radius: 3px;
  float: right;
  height: 100px;
  margin: 3px;
  padding: 3px;
  width: 295px;
  background-repeat: no-repeat;
  background-position: right center;
}
dl.node-type-list div.node-add-item-inner:hover {
  border-color: #AAAAAA;
  background-color: #eee;
}

dl.node-type-list div.node-add-tutorial-inner {
  background-image: url("picture1.png");
}
dl.node-type-list div.node-add-simplenews-inner {
  background-image: url("picture2.png");
}
dl.node-type-list div.node-add-book-inner {
  background-image: url("picture3.png");
}
/* etc... . */

افزودن دیدگاه جدید