十一步创建一个完美wordpress主题【十二】如何使用css定义你的外观重建你的主题

 

何使用css定义你的外观重建你的主题

  

文章目录

CSS可能非常复杂. 也可以难以置信的简单。 学习css之初我获得了很多帮助,同样我也非常愿意帮助别人通过我的例子获得收获。

下面我们将为你布局一个wordpress主题开发的兵工厂:

  • 一个为所有浏览器重置css的样式表和一个我们开始开启工作的健全标准。
  • 另一个通过巧妙方式重建我们排版基础的样式表
  • 一个仅适用于wordpress的样式表(保持前两个独立,是为了本例可以用于非wordpress系统)
  • 6个你想要的适于所有博客和网站的流式样式表,每一个都可以调整宽的。

我们这里用到的所有代码都是开源的,符合 GPL 协议,并且都可以在Your Theme Project Page页面看到。您可以随便阅读、复制和粘帖其中任何的文件。

要事先行,先在您的主题根目录下新建一个 “styles”文件夹,那 6 个样式表都会放在这个新文件夹里面,准备好制作那些 CSS 文件了吗?

重置 CSS

我们的重置css知识从著名的Eric Meyer’s famous Reset CSS拿来做了微小的改变。它的用途是是你的主题适用于任何浏览器。

它的使用非常简单,在你的style.css顶部加入以下代码:

1
2
/* Reset default browser styles */
@import url('styles/reset.css');

在各种浏览器下重新加载你的页面,很神奇吧。

重建 CSS

这个 Rebuild CSS 是我根据早期的 BluePrint CSS 样式表发明的,并且在 Thematic 主题里面加以完善了。这个 Rebuild CSS 的作用在于使页面的垂直边距有规律,方便调整。

我这个 Rebuild CSS 的特色是把两种不同的网页样式结合起来,即字体大小用 px,并采用相对行高,而其他的垂直边距(例如段落和列表)则使用 em。

这是什么意思呢?这方便您以后修改字体的大小——不需要做任何计算——其他的排版因素(例如段落和清单)就会自动调整垂直边距。

rebuild.css 的使用也很简单,在 reset.css 导入后添加以下代码:

1
2
/* Rebuild default browser styles */
@import url('styles/rebuild.css');

基本wordpress样式

WordPress 里面有我们每次都需要用到的格式,我所做的就是通过一个叫做 wp.css 的文件调用它们。

现在我们需要设定所有图片的排列方式——包括标题和画廊,同时设定引用的格式。您所需要做的只是为 blockquote 标签添加一个左对齐或者右对齐的 Class 属性。

您能猜测我们将如何使用 wp.css?

1
2
/* Basic WordPress Styles */
@import url('styles/wp.css');

你所需要的所有外观

 

对您的新主题,我已经采取了坚如磐石的布局,这个布局建立在 Sandbox 主题的基础上并且适合您的新 HTML 结构。一共有 6 种布局,其中每一种布局都是流动的(即宽度可以伸缩到符合您的浏览器窗口大小),并且可以简单地固定布局的宽度。这些布局的使用都很简单。在导入基本的布局注释语下面直接导入其中一个布局就好了,下面就是导入正文在中间的三栏布局的代码:

1
2
/* Import a basic layout */
@import url('styles/3c-b.css');

最简单的固定布局宽度的方法是在 wrapper div 标签里面添加 width 和 margin 属性:

1
2
3
4
#wrapper {
  margin: 0 auto;
  width: 960px;
}

额外的收获:菜单样式化

作为一种奖励,如果您从未创建一个无序的列表(由 wp_page_menu 自动生成的)并且想让这个列表好看一点,可以参考下面我创建 WordPress 主题时所用的代码:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
#access {
    margin: 0 0 1.5em 0;
    overflow: auto;
}
.skip-link {
    position:absolute;
        left:-9000px;
}
.menu ul {
    list-style: none;
    margin: 0;
}
.menu ul ul {
    display: none;
}
.menu li {
    display: inline;
}
.menu a {
    display: block;
    float: left;
}

简单,但已经领你入门,祝你好运

Posted on  by Ian Stewart

十一步创建一个完美wordpress主题【十一】侧边栏模板

 

侧边栏模板

  

文章目录

我知道你一直在耐心的等待这个。每个人都喜欢侧边栏模板。但是我们将做的和别人不同,我们的会更好一些。

自定义侧边栏模板功能

先说重点,对于侧边栏模板,我们需要它支持小工具。我们的侧边栏将拥有两个小工具区域。这样我们就可以把代码复用在两栏或三栏的主题上。

非常直观,我们在function.php中使用以下代码:

// Register widgetized areas
function theme_widgets_init() {
	// Area 1
	register_sidebar( array (
	'name' => 'Primary Widget Area',
	'id' => 'primary_widget_area',
	'before_widget' => '<li id="%1$s">',
	'after_widget' => "</li>",
	'before_title' => '<h3>',
	'after_title' => '</h3>',
  ) );

	// Area 2
	register_sidebar( array (
	'name' => 'Secondary Widget Area',
	'id' => 'secondary_widget_area',
	'before_widget' => '<li id="%1$s">',
	'after_widget' => "</li>",
	'before_title' => '<h3>',
	'after_title' => '</h3>',
  ) );
} // end theme_widgets_init

add_action( 'init', 'theme_widgets_init' );

现在我们获得了两个小工具区,主工具区和次工具区。当然你也可以取其它名字。现在在function.php中我们再加入超酷的自定义代码片段。

首先,我们将预设默认小工具:搜索框、静态页面、分类目录、日志存档、链接和元。我们不需要把这些默认小工具的代码写在 sidebar.php 里,我们将令 WordPress 自动把它们添加到小工具区域(这里要感谢  Ptah Dunbar )

$preset_widgets = array (
	'primary_widget_area'  => array( 'search', 'pages', 'categories', 'archives' ),
	'secondary_widget_area'  => array( 'links', 'meta' )
);
if ( isset( $_GET['activated'] ) ) {
	update_option( 'sidebars_widgets', $preset_widgets );
}
// update_option( 'sidebars_widgets', NULL );

现在,在我们的 Primary Widget 区域 (primary_widget_area),会自动显示搜索、静态页面、分类目录以及日志存档这四个小工具。而在 Secondary Widget 区域 (secondary_widget_area) 将会显示链接和元这两个小工具。只要激活 WordPress 主题,这些小工具就会自动显示。

看见最后一行 “ // update_option( ‘sidebars_widgets’, NULL ); ” 了吗?如果您想重启小工具的话,就把前面的两斜杠去掉(并替代前面那一行?)。我想您能猜到 “NULL” 表示没有小工具。

其次,我们将创建一个新的条件以便检测已有的小工具区域是否有小工具,这对我们以后写侧边栏代码很有帮助(谢谢Chaos Kaizer)。

// Check for static widgets in widget-ready areas
function is_sidebar_active( $index ){
  global $wp_registered_sidebars;

  $widgetcolums = wp_get_sidebars_widgets();

  if ($widgetcolums[$index]) return true;

	return false;
} // end is_sidebar_active

现在我们让这些代码片段发生作用。

编写侧边栏模板代码

在已有的动态小工具区域和预设小工具的基础上,我们创建的侧边栏模板将是您见过的最简单的模板之一。但是要记住,我们同时也通过 is_sidebar_active() 的 IF 语句把侧边栏固定。

下面就是侧边栏模板的代码:

<?php if ( is_sidebar_active('primary_widget_area') ) : ?>
		<div id="primary">
			<ul>
				<?php dynamic_sidebar('primary_widget_area'); ?>
			</ul>
		</div><!-- #primary .widget-area -->
<?php endif; ?>		

<?php if ( is_sidebar_active('secondary_widget_area') ) : ?>
		<div id="secondary">
			<ul>
				<?php dynamic_sidebar('secondary_widget_area'); ?>
			</ul>
		</div><!-- #secondary .widget-area -->
<?php endif; ?>

现在如果您进入 WordPress 后台的小工具页面,把任一小工具区域的小工具全部移除,那么这个条件语句就失效,侧边栏那个小工具区域就没有小工具了。

Posted on  by Ian Stewart

十一步创建一个完美wordpress主题【十】归档,作者,分类和标签模板

 

归档、作者、分类和标签模板

 

文章目录

正如我们在主页模板里做的 , 我们将创建一个主要模板,然后依据它创建其它模板,我们的主要模板是归档模板

归档模板的作用就是显示特定条件的博文,按日期、作者、分类、标签等。所以,基本上他很像主页模板,你只需读懂这些模板的字面意思,你就明白他们是干什么的。

开始我们的代码:

<?php get_header(); ?>
         <div id="container">
             <div id="content">
                 <div id="nav-above" class="navigation">
                 </div><!-- #nav-above -->
                 <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
                 </div><!-- #post-<?php the_ID(); ?> -->          
                 <div id="nav-below" class="navigation">
                 </div><!-- #nav-below -->                  
             </div><!-- #content -->
         </div><!-- #container -->
 <?php get_sidebar(); ?>
 <?php get_footer(); ?> 

归档模板

以下是归档模板的作用:

  1. 调用the_post()
  2. 检查这是什么模板
  3. 产生一个适当的模板
  4. 使用哪个 rewind_posts()函数倒序排列博文
  5. 执行wordpress循环

这是你archive.php的#content部分。注意顶部的Conditional Tags  检查我们在哪个模板里面。

<?php the_post(); ?>           
 <?php if ( is_day() ) : ?>
                 <h1 class="page-title"><?php printf( __( 'Daily Archives: <span>%s</span>', 'your-theme' ), get_the_time(get_option('date_format')) ) ?></h1>
 <?php elseif ( is_month() ) : ?>
                 <h1 class="page-title"><?php printf( __( 'Monthly Archives: <span>%s</span>', 'your-theme' ), get_the_time('F Y') ) ?></h1>
 <?php elseif ( is_year() ) : ?>
                 <h1 class="page-title"><?php printf( __( 'Yearly Archives: <span>%s</span>', 'your-theme' ), get_the_time('Y') ) ?></h1>
 <?php elseif ( isset($_GET['paged']) && !empty($_GET['paged']) ) : ?>
                 <h1 class="page-title"><?php _e( 'Blog Archives', 'your-theme' ) ?></h1>
 <?php endif; ?> 
 <?php rewind_posts(); ?> 
 <?php global $wp_query; $total_pages = $wp_query->max_num_pages; if ( $total_pages > 1 ) { ?>
                 <div id="nav-above">
                     <div class="nav-previous"><?php next_posts_link(__( '<span class="meta-nav">&laquo;</span> Older posts', 'your-theme' )) ?></div>
                     <div class="nav-next"><?php previous_posts_link(__( 'Newer posts <span>&raquo;</span>', 'your-theme' )) ?></div>
                 </div><!-- #nav-above -->
 <?php } ?>             
 <?php while ( have_posts() ) : the_post(); ?> 
                 <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
                     <h2 class="entry-title"><a href="<?php the_permalink(); ?>" title="<?php printf( __('Permalink to %s', 'your-theme'), the_title_attribute('echo=0') ); ?>" rel="bookmark"><?php the_title(); ?></a></h2> 
                     <div class="entry-meta">
                         <span class="meta-prep meta-prep-author"><?php _e('By ', 'your-theme'); ?></span>
                         <span class="author vcard"><a href="<?php echo get_author_link( false, $authordata->ID, $authordata->user_nicename ); ?>" title="<?php printf( __( 'View all posts by %s', 'your-theme' ), $authordata->display_name ); ?>"><?php the_author(); ?></a></span>
                         <span class="meta-sep"> | </span>
                         <span class="meta-prep meta-prep-entry-date"><?php _e('Published ', 'your-theme'); ?></span>
                         <span class="entry-date"><abbr title="<?php the_time('Y-m-d\TH:i:sO') ?>"><?php the_time( get_option( 'date_format' ) ); ?></abbr></span>
                         <?php edit_post_link( __( 'Edit', 'your-theme' ), "<span class=\"meta-sep\">|</span>\n\t\t\t\t\t\t<span class=\"edit-link\">", "</span>\n\t\t\t\t\t" ) ?>
                     </div><!-- .entry-meta --> 
                     <div class="entry-summary">
 <?php the_excerpt( __( 'Continue reading <span class="meta-nav">&raquo;</span>', 'your-theme' )  ); ?>
                     </div><!-- .entry-summary --> 
                     <div class="entry-utility">
                         <span class="cat-links"><span><?php _e( 'Posted in ', 'your-theme' ); ?></span><?php echo get_the_category_list(', '); ?></span>
                         <span class="meta-sep"> | </span>
                         <?php the_tags( '<span><span class="entry-utility-prep entry-utility-prep-tag-links">' . __('Tagged ', 'your-theme' ) . '</span>', ", ", "</span>\n\t\t\t\t\t\t<span class=\"meta-sep\">|</span>\n" ) ?>
                         <span class="comments-link"><?php comments_popup_link( __( 'Leave a comment', 'your-theme' ), __( '1 Comment', 'your-theme' ), __( '% Comments', 'your-theme' ) ) ?></span>
                         <?php edit_post_link( __( 'Edit', 'your-theme' ), "<span class=\"meta-sep\">|</span>\n\t\t\t\t\t\t<span class=\"edit-link\">", "</span>\n\t\t\t\t\t\n" ) ?>
                     </div><!-- #entry-utility -->
                 </div><!-- #post-<?php the_ID(); ?> --> 
 <?php endwhile; ?>           

 <?php global $wp_query; $total_pages = $wp_query->max_num_pages; if ( $total_pages > 1 ) { ?>
                 <div id="nav-below">
                     <div class="nav-previous"><?php next_posts_link(__( '<span class="meta-nav">&laquo;</span> Older posts', 'your-theme' )) ?></div>
                     <div class="nav-next"><?php previous_posts_link(__( 'Newer posts <span>&raquo;</span>', 'your-theme' )) ?></div>
                 </div><!-- #nav-below -->
 <?php } ?>

作者模板

作者模板你不需要修改太多,你会喜欢它。从archive.php复制过来,你只需要修改标题段。

<h1 class=”page-title author”><?php printf( __( ‘Author Archives: <span>%s</span>’, ‘your-theme’ ), “<a class=’url fn n’ href=’$authordata->user_url’ title=’$authordata->display_name’ rel=’me’>$authordata->display_name</a>” ) ?></h1>
<?php $authordesc = $authordata->user_description; if ( !empty($authordesc) ) echo apply_filters( ‘archive_meta’, ‘<div class=”archive-meta”>’ . $authordesc . ‘</div>’ ); ?>

很简单是吗?

分类模板

复制archive.php 重命名为 category.php.

打开function.php,给分类模板加点功能。

// For category lists on category archives: Returns other categories except the current one (redundant)
 function cats_meow($glue) {
     $current_cat = single_cat_title( '', false );
     $separator = "\n";
     $cats = explode( $separator, get_the_category_list($separator) );
     foreach ( $cats as $i => $str ) {
         if ( strstr( $str, ">$current_cat<" ) ) {
             unset($cats[$i]);
             break;
         }
     }
     if ( empty($cats) )
         return false;
     return trim(join( $glue, $cats ));
 } // end cats_meow
 
 

我们自定义的程序cats_meow() 会将当前分类从分类页面中清除。

现在回到category.php, 用以下代码替换页面标题段:

<h1 class="page-title"><?php _e( 'Category Archives:', 'your-theme' ) ?> <span><?php single_cat_title() ?></span></span></h1>
 <?php $categorydesc = category_description(); if ( !empty($categorydesc) ) echo apply_filters( 'archive_meta', '<div>' . $categorydesc . '</div>' ); ?>

在 .entry-utility div找到 …

<span class="cat-links"><span class="entry-utility-prep entry-utility-prep-cat-links"><?php _e( 'Posted in ', 'your-theme' ); ?></span><?php echo get_the_category_list(', '); ?></span>

替换为…

<?php if ( $cats_meow = cats_meow(', ') ) : // Returns categories other than the one queried ?>
                         <span class="cat-links"><?php printf( __( 'Also posted in %s', 'your-theme' ), $cats_meow ) ?></span>
                         <span class="meta-sep"> | </span>
 <?php endif ?>

标签模板

标签模板和分类模板几乎一样,你知道的: 复制archive.php a重命名为 tag.php.

打开function.php加点功能:

// For tag lists on tag archives: Returns other tags except the current one (redundant)
 function tag_ur_it($glue) {
     $current_tag = single_tag_title( '', '',  false );
     $separator = "\n";
     $tags = explode( $separator, get_the_tag_list( "", "$separator", "" ) );
     foreach ( $tags as $i => $str ) {
         if ( strstr( $str, ">$current_tag<" ) ) {
             unset($tags[$i]);
             break;
         }
     }
     if ( empty($tags) )
         return false;
     return trim(join( $glue, $tags ));
 } // end tag_ur_it

替换页面标题:

<h1 class="page-title"><?php _e( 'Tag Archives:''your-theme' ) ?> <span><?php single_tag_title() ?></span></h1>

在 .entry-utility, 找到 …

<?php the_tags( '<span><span>' . __('Tagged ''your-theme' ) . '</span>'", ""</span>\n\t\t\t\t\t\t<span class=\"meta-sep\">|</span>\n" ) ?>

替换为…

<?php if ( $tag_ur_it = tag_ur_it(', ') ) : // Returns tags other than the one queried ?>                    <span class="tag-links"><?php printf( __( 'Also tagged %s', 'your-theme' ), $tag_ur_it ) ?></span> <?php endif; ?>  

好了!

Posted on  by Ian Stewart

十一步创建一个完美wordpress主题【九】搜索模板和页面模板

 

wordpress搜索模板和页面模板

 

文章目录

搜索模板和页面模板 对任何主题来讲都异常重要. 同时他们有非常容易编码,对于这两个模板,我们仍然使用模板的模板创建。

<?php get_header(); ?>
         <div id="container">
             <div id="content">
                 <div id="nav-above">
                 </div><!-- #nav-above -->
                 <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
                 </div><!-- #post-<?php the_ID(); ?> -->        
                 <div id="nav-below">
                 </div><!-- #nav-below -->                  
             </div><!-- #content -->
         </div><!-- #container -->
 <?php get_sidebar(); ?>
 <?php get_footer(); ?>

当然了,每个模板也各有不同。

搜索模板

在search.php中我们重新引入loop循环,这一次我们使用if语句以防我们没有文章输出。

详情参照代码:

<?php get_header(); ?>
         <div id="container">
             <div id="content">
 <?php if ( have_posts() ) : ?>             
 <?php while ( have_posts() ) : the_post() ?>
 <!-- this is our loop -->
 <?php endwhile; ?>
 <?php else : ?>
 <!-- here's where we'll put a search form if there're no posts -->
 <?php endif; ?>        
             </div><!-- #content -->
         </div><!-- #container -->
 <?php get_sidebar(); ?>
 <?php get_footer(); ?>

非常简洁是吗?

我会保持所有类似index模板的结构类似:博客标题、meta信息、内容或摘要,实用链接。但wordpress在搜索的时候同时会搜索页面页,页面页中我们不想显示实用链接。所以我们需要使用if语句来判断是博文还是页面页。

<?php if ( $post->post_type == 'post' ) { ?>
<?php } ?>

页面判断,代码如下:

<?php if ( have_posts() ) : ?>

				<h1><?php _e( 'Search Results for: ', 'your-theme' ); ?><span><?php the_search_query(); ?></span></h1>

<?php global $wp_query; $total_pages = $wp_query->max_num_pages; if ( $total_pages > 1 ) { ?>
				<div id="nav-above">
					<div><?php next_posts_link(__( '<span>&laquo;</span> Older posts', 'your-theme' )) ?></div>
					<div><?php previous_posts_link(__( 'Newer posts <span>&raquo;</span>', 'your-theme' )) ?></div>
				</div><!-- #nav-above -->
<?php } ?>							

<?php while ( have_posts() ) : the_post() ?>

				<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
					<h2><a href="<?php the_permalink(); ?>" title="<?php printf( __('Permalink to %s', 'your-theme'), the_title_attribute('echo=0') ); ?>" rel="bookmark"><?php the_title(); ?></a></h2>

<?php if ( $post->post_type == 'post' ) { ?>
					<div>
						<span><?php _e('By ', 'your-theme'); ?></span>
						<span><a href="<?php echo get_author_link( false, $authordata->ID, $authordata->user_nicename ); ?>" title="<?php printf( __( 'View all posts by %s', 'your-theme' ), $authordata->display_name ); ?>"><?php the_author(); ?></a></span>
						<span> | </span>
						<span><?php _e('Published ', 'your-theme'); ?></span>
						<span><abbr title="<?php the_time('Y-m-d\TH:i:sO') ?>"><?php the_time( get_option( 'date_format' ) ); ?></abbr></span>
						<?php edit_post_link( __( 'Edit', 'your-theme' ), "<span class=\"meta-sep\">|</span>\n\t\t\t\t\t\t<span class=\"edit-link\">", "</span>\n\t\t\t\t\t" ) ?>
					</div><!-- .entry-meta -->
<?php } ?>

					<div>
<?php the_excerpt( __( 'Continue reading <span>&raquo;</span>', 'your-theme' )  ); ?>
<?php wp_link_pages('before=<div>' . __( 'Pages:', 'your-theme' ) . '&after=</div>') ?>
					</div><!-- .entry-summary -->

<?php if ( $post->post_type == 'post' ) { ?>
					<div>
						<span><span><?php _e( 'Posted in ', 'your-theme' ); ?></span><?php echo get_the_category_list(', '); ?></span>
						<span> | </span>
						<?php the_tags( '<span><span>' . __('Tagged ', 'your-theme' ) . '</span>', ", ", "</span>\n\t\t\t\t\t\t<span class=\"meta-sep\">|</span>\n" ) ?>
						<span><?php comments_popup_link( __( 'Leave a comment', 'your-theme' ), __( '1 Comment', 'your-theme' ), __( '% Comments', 'your-theme' ) ) ?></span>
						<?php edit_post_link( __( 'Edit', 'your-theme' ), "<span class=\"meta-sep\">|</span>\n\t\t\t\t\t\t<span class=\"edit-link\">", "</span>\n\t\t\t\t\t\n" ) ?>
					</div><!-- #entry-utility -->
<?php } ?>
				</div><!-- #post-<?php the_ID(); ?> -->

<?php endwhile; ?>

<?php global $wp_query; $total_pages = $wp_query->max_num_pages; if ( $total_pages > 1 ) { ?>
				<div id="nav-below">
					<div><?php next_posts_link(__( '<span>&laquo;</span> Older posts', 'your-theme' )) ?></div>
					<div><?php previous_posts_link(__( 'Newer posts <span>&raquo;</span>', 'your-theme' )) ?></div>
				</div><!-- #nav-below -->
<?php } ?>			

<?php else : ?>

				<div id="post-0">
					<h2><?php _e( 'Nothing Found', 'your-theme' ) ?></h2>
					<div>
						<p><?php _e( 'Sorry, but nothing matched your search criteria. Please try again with some different keywords.', 'your-theme' ); ?></p>
	<?php get_search_form(); ?>
					</div><!-- .entry-content -->
				</div>

<?php endif; ?>

页面模板

以下是一个完美的wordpress页面模板:

<?php get_header(); ?>

		<div id="container">
			<div id="content">

<?php the_post(); ?>

				<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
					<h1><?php the_title(); ?></h1>
					<div>
<?php the_content(); ?>
<?php wp_link_pages('before=<div>' . __( 'Pages:', 'your-theme' ) . '&after=</div>') ?>
<?php edit_post_link( __( 'Edit', 'your-theme' ), '<span>', '</span>' ) ?>
					</div><!-- .entry-content -->
				</div><!-- #post-<?php the_ID(); ?> -->			

<?php if ( get_post_custom_values('comments') ) comments_template() // Add a custom field with Name and Value of "comments" to enable comments on this page ?>			

			</div><!-- #content -->
		</div><!-- #container -->

<?php get_sidebar(); ?>
<?php get_footer(); ?>

Posted on  by Ian Stewart

十一步创建一个完美wordpress主题【八】评论模板

 

wordpress评论模板

 

  

文章目录

我讨厌评论模板. 他可能会相当困扰。在2.7版本中,wordpress引入了一个简单的评论模板,但是不能把留言和引用通告分开,或者自定义评论标记。它仍然令人困惑.很幸运,我已经为你整理好了,虽然还是有些困惑,但是毕竟整理出来了。在这个例子中,我将向你展示发生了什么,一些自定义的代码片段,你可以把这些代码片段放在function.php中。希望它能起到作用,至少是一个顽皮的评论模板。

让我们看看我们要做的事情.

  1.  阻止搜索爬虫加载评论和受保护文章。
  2. 检查是否有评论
  3. 检测评论数量和引用通告(或ping)。
  4. 如果有评论,展示评论并附上导航和页码。
  5. 如果有引用通告,展示之。
  6. 如果评论是开启的,展示回复表单。

这个模板有很多代码,但总结起来也就这么些。

自定义留言回调和引用通告

WordPress 2.7 允许通过 wp_list_comments() 函数方便有序地调用单独日志的留言和引用。如果您喜欢那样,那就很方便。但是我们不喜欢,我想要把评论里面的留言和引用分开。为了实现这种结果,您需要对留言和引用进行自定义回调,把下面代码插入到 functions.php 文件:

// Custom callback to list comments in the your-theme style
 function custom_comments($comment, $args, $depth) {
   $GLOBALS['comment'] = $comment;
     $GLOBALS['comment_depth'] = $depth;
   ?>
     <li id="comment-<?php comment_ID() ?>" <?php comment_class() ?>>
         <div class="comment-author vcard"><?php commenter_link() ?></div>
         <div class="comment-meta"><?php printf(__('Posted %1$s at %2$s <span>|</span> <a href="%3$s" title="Permalink to this comment">Permalink</a>', 'your-theme'),
                     get_comment_date(),
                     get_comment_time(),
                     '#comment-' . get_comment_ID() );
                     edit_comment_link(__('Edit', 'your-theme'), ' <span class="meta-sep">|</span> <span class="edit-link">', '</span>'); ?></div>
   <?php if ($comment->comment_approved == '0') _e("\t\t\t\t\t<span class='unapproved'>Your comment is awaiting moderation.</span>\n", 'your-theme') ?>
           <div class="comment-content">
             <?php comment_text() ?>
         </div>
         <?php // echo the comment reply link
             if($args['type'] == 'all' || get_comment_type() == 'comment') :
                 comment_reply_link(array_merge($args, array(
                     'reply_text' => __('Reply','your-theme'),
                     'login_text' => __('Log in to reply.','your-theme'),
                     'depth' => $depth,
                     'before' => '<div>',
                     'after' => '</div>'
                 )));
             endif;
         ?>
 <?php } // end custom_comments
 
看起来有一点乱对吗?不过你已经渐入佳境。现在到创建评论结构的时候了,我想下面那个结构很漂亮,并且能够让您只通过 CSS 就能更改很多—— 如果您真的想修改这个结构。我们还需要调用一个特殊的自定义函数,这个函数将会显示符合 microformat hcard 架构的头像结构。

 

// Produces an avatar image with the hCard-compliant photo class
 function commenter_link() {
     $commenter = get_comment_author_link();
     if ( ereg( '<a[^>]* class=[^>]+>', $commenter ) ) {
         $commenter = ereg_replace( '(<a[^>]* class=[\'"]?)', '\\1url ' , $commenter );
     } else {
         $commenter = ereg_replace( '(<a )/', '\\1class="url "' , $commenter );
     }
     $avatar_email = get_comment_author_email();
     $avatar = str_replace( "class='avatar", "class='photo avatar", get_avatar( $avatar_email, 80 ) );
     echo $avatar . ' <span>' . $commenter . '</span>';
 } // end commenter_link
如果想改变头像的尺寸,您只需要改一下 get_avatar($avatar_email, 80) 里面的 80 就可以了,80 表示头像的大小,单位是像素。

评论模板

没有把您吓跑吧?诚然,并不是很可怕。下面是整个评论模板代码,上面有些 PHP 注释,以便您的理解。

<?php /* The Comments Template — with, er, comments! */ ?>
            <div id="comments">
<?php /* Run some checks for bots and password protected posts */ ?>
<?php
    $req = get_option('require_name_email'); // Checks if fields are required.
    if ( 'comments.php' == basename($_SERVER['SCRIPT_FILENAME']) )
        die ( 'Please do not load this page directly. Thanks!' );
    if ( ! empty($post->post_password) ) :
        if ( $_COOKIE['wp-postpass_' . COOKIEHASH] != $post->post_password ) :
?>
                <div><?php _e('This post is password protected. Enter the password to view any comments.', 'your-theme') ?></div>
            </div><!-- .comments -->
<?php
        return;
    endif;
endif;
?>   
<?php /* See IF there are comments and do the comments stuff! */ ?>
<?php if ( have_comments() ) : ?>   
<?php /* Count the number of comments and trackbacks (or pings) */
$ping_count = $comment_count = 0;
foreach ( $comments as $comment )
    get_comment_type() == "comment" ? ++$comment_count : ++$ping_count;
?>   
<?php /* IF there are comments, show the comments */ ?>
<?php if ( ! empty($comments_by_type['comment']) ) : ?>   
                <div id="comments-list">
                    <h3><?php printf($comment_count > 1 ? __('<span>%d</span> Comments', 'your-theme') : __('<span>One</span> Comment', 'your-theme'), $comment_count) ?></h3>   
<?php /* If there are enough comments, build the comment navigation  */ ?>
<?php $total_pages = get_comment_pages_count(); if ( $total_pages > 1 ) : ?>
                    <div id="comments-nav-above">
                                <div><?php paginate_comments_links(); ?></div>
                    </div><!-- #comments-nav-above -->
<?php endif; ?>                   
  
<?php /* An ordered list of our custom comments callback, custom_comments(), in functions.php   */ ?>
                    <ol>
<?php wp_list_comments('type=comment&callback=custom_comments'); ?>
                    </ol>   
<?php /* If there are enough comments, build the comment navigation */ ?>
<?php $total_pages = get_comment_pages_count(); if ( $total_pages > 1 ) : ?>
                <div id="comments-nav-below">
                        <div><?php paginate_comments_links(); ?></div>
            </div><!-- #comments-nav-below -->
<?php endif; ?>                      
                </div><!-- #comments-list .comments -->   
<?php endif; /* if ( $comment_count ) */ ?>   
<?php /* If there are trackbacks(pings), show the trackbacks  */ ?>
<?php if ( ! empty($comments_by_type['pings']) ) : ?>   
                <div id="trackbacks-list">
                    <h3><?php printf($ping_count > 1 ? __('<span>%d</span> Trackbacks', 'your-theme') : __('<span>One</span> Trackback', 'your-theme'), $ping_count) ?></h3>   
<?php /* An ordered list of our custom trackbacks callback, custom_pings(), in functions.php   */ ?>
                    <ol>
<?php wp_list_comments('type=pings&callback=custom_pings'); ?>
                    </ol>                
                </div><!-- #trackbacks-list .comments -->              
<?php endif /* if ( $ping_count ) */ ?>
<?php endif /* if ( $comments ) */ ?>  
<?php /* If comments are open, build the respond form */ ?>
<?php if ( 'open' == $post->comment_status ) : ?>
                <div id="respond">
                    <h3><?php comment_form_title( __('Post a Comment', 'your-theme'), __('Post a Reply to %s', 'your-theme') ); ?></h3>   
                    <div id="cancel-comment-reply"><?php cancel_comment_reply_link() ?></div>   
<?php if ( get_option('comment_registration') && !$user_ID ) : ?>
                    <p id="login-req"><?php printf(__('You must be <a href="%s" title="Log in">logged in</a> to post a comment.', 'your-theme'),
                    get_option('siteurl') . '/wp-login.php?redirect_to=' . get_permalink() ) ?></p>   
<?php else : ?>
                    <div>      
                        <form id="commentform" action="<?php echo get_option('siteurl'); ?>/wp-comments-post.php" method="post">   
<?php if ( $user_ID ) : ?>
                            <p id="login"><?php printf(__('<span>Logged in as <a href="%1$s" title="Logged in as %2$s">%2$s</a>.</span> <span><a href="%3$s" title="Log out of this account">Log out?</a></span>', 'your-theme'),
                                get_option('siteurl') . '/wp-admin/profile.php',
                                wp_specialchars($user_identity, true),
                                wp_logout_url(get_permalink()) ) ?></p>   
<?php else : ?>   
                            <p id="comment-notes"><?php _e('Your email is <em>never</em> published nor shared.', 'your-theme') ?> <?php if ($req) _e('Required fields are marked <span>*</span>', 'your-theme') ?></p>   
              <div id="form-section-author">
                                <div><label for="author"><?php _e('Name', 'your-theme') ?></label> <?php if ($req) _e('<span>*</span>', 'your-theme') ?></div>
                                <div><input id="author" name="author" type="text" value="<?php echo $comment_author ?>" size="30" maxlength="20" tabindex="3" /></div>
              </div><!-- #form-section-author .form-section -->   
              <div id="form-section-email">
                                <div><label for="email"><?php _e('Email', 'your-theme') ?></label> <?php if ($req) _e('<span>*</span>', 'your-theme') ?></div>
                                <div><input id="email" name="email" type="text" value="<?php echo $comment_author_email ?>" size="30" maxlength="50" tabindex="4" /></div>
              </div><!-- #form-section-email .form-section -->   
              <div id="form-section-url">
                                <div><label for="url"><?php _e('Website', 'your-theme') ?></label></div>
                                <div><input id="url" name="url" type="text" value="<?php echo $comment_author_url ?>" size="30" maxlength="50" tabindex="5" /></div>
              </div><!-- #form-section-url .form-section -->   
<?php endif /* if ( $user_ID ) */ ?>   
              <div id="form-section-comment">
                                <div><label for="comment"><?php _e('Comment', 'your-theme') ?></label></div>
                                <div><textarea id="comment" name="comment" cols="45" rows="8" tabindex="6"></textarea></div>
              </div><!-- #form-section-comment .form-section -->   
              <div id="form-allowed-tags">
                  <p><span><?php _e('You may use these <abbr title="HyperText Markup Language">HTML</abbr> tags and attributes:', 'your-theme') ?></span> <code><?php echo allowed_tags(); ?></code></p>
              </div>   
<?php do_action('comment_form', $post->ID); ?>   
                            <div><input id="submit" name="submit" type="submit" value="<?php _e('Post Comment', 'your-theme') ?>" tabindex="7" /><input type="hidden" name="comment_post_ID" value="<?php echo $id; ?>" /></div>   
<?php comment_id_fields(); ?>     
<?php /* Just … end everything. We're done here. Close it up. */ ?>     
                        </form><!-- #commentform -->
                    </div><!-- .formcontainer -->
<?php endif /* if ( get_option('comment_registration') && !$user_ID ) */ ?>                 </div><!-- #respond -->
<?php endif /* if ( 'open' == $post->comment_status ) */ ?>

就这么多了,您已经创建了一个漂亮的自定义评论模板。

Posted on  by Ian Stewart

十一步创建一个完美wordpress主题【七】Single Post, Post Attachment,404 Templates

 

 Single Post, Post Attachment, & 404 模板

 

文章目录

你已经创建了index.php文件,现在开始创建其它模板文件。

模板的模板

single.php 以及其它的模板的结构很多都是和 index.php 一样的,事实上,您可以把它看成模板的模板。结构如下

<?php get_header(); ?>
		<div id="container">
			<div id="content">
				<div id="nav-above">
				</div><!-- #nav-above -->
				<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
				</div><!-- #post-<?php the_ID(); ?> -->
				<div id="nav-below">
				</div><!-- #nav-below -->
                          </div><!-- #content -->
		</div><!-- #container -->
<?php get_sidebar(); ?>
<?php get_footer(); ?>

但是也会有些不同,先从 the_post() 和 comments_template() 开始吧。

我们将要在页面顶部在content的div开始后调用the_post()。我们只显示一篇博文,亏了有the_permalink(),我们不需使用loop循环。

然这是一篇单独日志,我们需要调用 comments_template() 函数。因为我们要把留言和引用分开,所以代码该是这样:

<?php comments_template('', true); ?>
上面的代码需要放在 </div><!– #content –> 之前,</div><!– #nav-below –> 之后。

单独页导航

这里,我们将会用 next_post_link() 替代 previous_posts_link(), 用 previous_post_link() 替代 next_posts_link(),他们的作用就和他们的名称一样。

				<div id="nav-above">
					<div><?php previous_post_link( '%link', '<span>&laquo;</span> %title' ) ?></div>
					<div><?php next_post_link( '%link', '%title <span>&raquo;</span>' ) ?></div>
				</div><!-- #nav-above -->
				<div id="nav-below">
					<div><?php previous_post_link( '%link', '<span>&laquo;</span> %title' ) ?></div>
					<div><?php next_post_link( '%link', '%title <span>&raquo;</span>' ) ?></div>
				</div><!-- #nav-below -->

单独日志标题

如果您还记得 header.php 那一课,就会发现我们用一个动态的 IF 语句方便屏幕浏览器识别单独日志标题。在这里以及后面的主题模板,我们将用 H1 标签获取文章标题。我想你会知道下面的代码该放到那里去。

					<h1><?php the_title(); ?></h1>

单独日志实用链接

文章的实用性非常复杂。我想你会发现站在别人肩上和一次性找到正确答案的好处。

在我们查看这段代码前想一想为什么这么复杂。因为评论会在wordpress中用在很多不同的场景中:打开评论和引用通告;只打开引用通告;只打开评论;都关闭。这就意味着大量的if语句。

这会非常令人沮丧,好在代码已经添加了注释并且你可以仔细寻找if 和elseif表达式来解决问题。们还想添加一个页面永久链接以及 RSS 链接,这对跟踪开发对话有用。

					<div>
					<?php printf( __( 'This entry was posted in %1$s%2$s. Bookmark the <a href="%3$s" title="Permalink to %4$s" rel="bookmark">permalink</a>. Follow any comments here with the <a href="%5$s" title="Comments RSS to %4$s" rel="alternate" type="application/rss+xml">RSS feed for this post</a>.', 'your-theme' ),
						get_the_category_list(', '),
						get_the_tag_list( __( ' and tagged ', 'your-theme' ), ', ', '' ),
						get_permalink(),
						the_title_attribute('echo=0'),
						comments_rss() ) ?>
<?php if ( ('open' == $post->comment_status) && ('open' == $post->ping_status) ) : // Comments and trackbacks open ?>
						<?php printf( __( '<a href="#respond" title="Post a comment">Post a comment</a> or leave a trackback: <a href="%s" title="Trackback URL for your post" rel="trackback">Trackback URL</a>.', 'your-theme' ), get_trackback_url() ) ?>
<?php elseif ( !('open' == $post->comment_status) && ('open' == $post->ping_status) ) : // Only trackbacks open ?>
						<?php printf( __( 'Comments are closed, but you can leave a trackback: <a href="%s" title="Trackback URL for your post" rel="trackback">Trackback URL</a>.', 'your-theme' ), get_trackback_url() ) ?>
<?php elseif ( ('open' == $post->comment_status) && !('open' == $post->ping_status) ) : // Only comments open ?>
						<?php _e( 'Trackbacks are closed, but you can <a href="#respond" title="Post a comment">post a comment</a>.', 'your-theme' ) ?>
<?php elseif ( !('open' == $post->comment_status) && !('open' == $post->ping_status) ) : // Comments and trackbacks closed ?>
						<?php _e( 'Both comments and trackbacks are currently closed.', 'your-theme' ) ?>
<?php endif; ?>
<?php edit_post_link( __( 'Edit', 'your-theme' ), "\n\t\t\t\t\t<span class=\"edit-link\">", "</span>" ) ?>
					</div><!-- .entry-utility -->

并不是太糟对吗?

单独日志内容输出

在 wp_link_pages() 之后加上如下代码即可。译者注:此时别忘了在container这个div后面加上the_post()。

<?php the_content(); ?>
<?php wp_link_pages('before=<div>' . __( 'Pages:', 'your-theme' ) . '&after=</div>') ?>

单独日志附档

并不是很多人会用到单独日志附档,但是它还是有点意思。当你为你的日志附加一个照片时,你就用到了它。实际上不仅仅是照片,你可以创建视频、音频、应用程序模板,分别给他们命名成video.php、audio.php、application.php等。单独附档确实可以让你的wordpress充满创意。

简易的方法是将所有的single.php内容拷贝到attachment.php,并作如下改变。

首先,删除顶部导航,此时我们不使用它。替代为链接到父页面的页面标题。

<h1><a href="<?php echo get_permalink($post->post_parent) ?>" title="<?php printf( __( 'Return to %s', 'your-theme' ), wp_specialchars( get_the_title($post->post_parent), 1 ) ) ?>" rev="attachment"><span>&laquo; </span><?php echo get_the_title($post->post_parent) ?></a></h1>

因为页面标题已经被h1包装,所以文章标题需要使用h2页面包装起来。

					<h2><?php the_title(); ?></h2>

现在,因为我们的附档模板需要实际显示附档,我们的内容需要反映这一点。因为主要附档是图片,所以我们使用if语句来表现出来。

					<div>
						<div>
<?php if ( wp_attachment_is_image( $post->id ) ) : $att_image = wp_get_attachment_image_src( $post->id, "medium"); ?>
						<p><a href="<?php echo wp_get_attachment_url($post->id); ?>" title="<?php the_title(); ?>" rel="attachment"><img src="<?php echo $att_image[0];?>" width="<?php echo $att_image[1];?>" height="<?php echo $att_image[2];?>"  alt="<?php $post->post_excerpt; ?>" /></a>
						</p>
<?php else : ?>
						<a href="<?php echo wp_get_attachment_url($post->ID) ?>" title="<?php echo wp_specialchars( get_the_title($post->ID), 1 ) ?>" rel="attachment"><?php echo basename($post->guid) ?></a>
<?php endif; ?>
						</div>
						<div><?php if ( !empty($post->post_excerpt) ) the_excerpt() ?></div>
<?php the_content( __( 'Continue reading <span>&raquo;</span>', 'your-theme' )  ); ?>
<?php wp_link_pages('before=<div>' . __( 'Pages:', 'your-theme' ) . '&after=</div>') ?>
					</div><!-- .entry-content -->

再删除底部链接导航。

 404 模板

进入错误页面模板,输入以下内容:

				<div id="post-0">
					<h1><?php _e( 'Not Found', 'your-theme' ); ?></h1>
					<div>
						<p><?php _e( 'Apologies, but we were unable to find what you were looking for. Perhaps searching will help.', 'your-theme' ); ?></p>
	<?php get_search_form(); ?>
					</div><!-- .entry-content -->
				</div><!-- #post-0 -->

Posted on  by Ian Stewart

十一步创建一个完美wordpress主题【六】index模板

 

index模板

 
页面导航
index.php非常重要。不仅仅是因为当你丢失其它模板(如category.php,tag.php等)时它会替代,而且因为做好了这个模板将会帮助我们剩下的模板开发的坚冰。

loop循环

如下:

<?php while ( have_posts() ) : the_post() ?> <?php endwhile; ?>

键入以上代码试一试:再键入以下加粗部分试一试:

<?php while ( have_posts() ) : the_post() ?> <?php the_content(); ?>
<?php endwhile; ?>
再改一改:
<ul>
<?php while ( have_posts() ) : the_post() ?>
<li><?php the_excerpt(); ?>
</li>
<?php endwhile; ?>
</ul>

通过以上实验,我相信你很快理解了 the_content()和 the_excerpt() 的不同。

while和 endwhile是循环的主体,你在里面可以防止一些模板标签来循环输出。

好的,让我们制作一个更酷的循环。你需要了解More Tag 和Next Page Tag 。

<div class="entry-content"> <?php the_content( __( 'Continue reading <span>&raquo;</span>''your-theme' )  ); ?> <?php wp_link_pages('before=<div>' . __( 'Pages:''your-theme' ) . '&after=</div>') ?> </div><!-- .entry-content -->

以下是加上链接的文章标题:

<h2 class="entry-title"> <a href="<?php the_permalink(); ?>" title="<?php printf( __('Permalink to %s', 'your-theme'), the_title_attribute('echo=0') ); ?>" rel="bookmark"><?php the_title(); ?> </a></h2>

添加上叫做postmeta的信息,这些数据描述了每篇post的具体细节。

我们看看我们现在的循环体,以下代码都放置在id为content的div内

<?php /* The Loop — with comments! */ ?> <?php while ( have_posts() ) : the_post() ?> <?php /* Create a div with a unique ID thanks to the_ID() and semantic classes with post_class() */ ?>                 <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>> <?php /* an h2 title */ ?>                     <h2 class="entry-title"><a href="<?php the_permalink(); ?>" title="<?php printf( __('Permalink to %s', 'your-theme'), the_title_attribute('echo=0') ); ?>" rel="bookmark"><?php the_title(); ?></a></h2> <?php /* Microformatted, translatable post meta */ ?>                     <div class="entry-meta">                         <span class="meta-prep meta-prep-author"><?php _e('By ''your-theme'); ?></span>                         <span class="author vcard"> <a class="url fn n" href="<?php echo get_author_link( false, $authordata->ID, $authordata->user_nicename ); ?>" title="<?php printf( __( 'View all posts by %s', 'your-theme' ), $authordata->display_name ); ?>"> <?php the_author(); ?></a></span>                         <span class="meta-sep"> | </span>                         <span class="meta-prep meta-prep-entry-date"><?php _e('Published ''your-theme'); ?></span>                         <span class="entry-date"><abbr class="published" title="<?php the_time('Y-m-d\TH:i:sO') ?>"><?php the_time( get_option( 'date_format' ) ); ?></abbr></span>                       <?php edit_post_link( __( 'Edit''your-theme' ), "<span class=\"meta-sep\">|</span>\n\t\t\t\t\t\t<span class=\"edit-link\">""</span>\n\t\t\t\t\t" ) ?>                     </div><!-- .entry-meta --> <?php /* The entry content */ ?>                     <div class="entry-content"> <?php the_content( __( 'Continue reading <span>&raquo;</span>''your-theme' )  ); ?> <?php wp_link_pages('before=<div>' . __( 'Pages:''your-theme' ) . '&after=</div>') ?> </div><!-- .entry-content --> <?php /* Microformatted category and tag links along with a comments link */ ?>                     <div class="entry-utility">                         <span class="cat-links"> <span class="entry-utility-prep entry-utility-prep-cat-links"><?php _e( 'Posted in ''your-theme' ); ?></span><?php echo get_the_category_list(', '); ?></span>                         <span class="meta-sep"> | </span>                         <?php the_tags( '<span><span>' . __('Tagged ''your-theme' ) . '</span>'", ""</span>\n\t\t\t\t\t\t<span class=\"meta-sep\">|</span>\n" ) ?>                         <span class="comments-link"><?php comments_popup_link( __( 'Leave a comment''your-theme' ), __( '1 Comment''your-theme' ), __( '% Comments''your-theme' ) ) ?></span>                         <?php edit_post_link( __( 'Edit''your-theme' ), "<span class=\"meta-sep\">|</span>\n\t\t\t\t\t\t<span class=\"edit-link\">""</span>\n\t\t\t\t\t\n" ) ?>                     </div><!-- #entry-utility -->                 </div><!-- #post-<?php the_ID(); ?> --> 
<?php /* Close up the post div and then end the loop with endwhile */ ?> <?php endwhile; ?>

 

导航

制作导航需要模板标签: next_posts_link() 和 previous_posts_link().  WordPress codex 上做了如下解释.

next posts link
This creates a link to the previous posts. Yes, it says “next posts,” but it’s named that just to confuse you.
previous posts link
This creates a link to the next posts. Yes, it says “previous posts,” but it’s named that just to confuse you.

正如index.php中的其他事情一样,博客导航在你初次创建的时候需要加倍注意,因为我们几乎在博客的每一个页面中使用。

我喜欢将博客导航放置在内容的上面或下面。这看你怎么用,当然你也可以不用,如下:

1
2
3
.single #nav-above {
    display:none;
}

这个 CSS 代码将会隐藏单独日志内容上面的文章导航功能

如果没有导航网页,我们也想隐藏文章导航功能。比如,如果没有较旧的文章,我们就不想输出任何的导航代码。这点可以通过以下代码实现:

1
2
<?php global $wp_query; $total_pages = $wp_query->max_num_pages; if ( $total_pages > 1 ) { ?>
<?php } ?>

这个代码表示如果循环页面里最大的页码大于1,那么就输出导航代码,执行导航功能。

下面就是我们需要的代码,其中顶部导航代码在循环开始之前,底部导航代码在循环结束之后:

<?php /* Top post navigation */ ?> <?php global $wp_query$total_pages $wp_query->max_num_pages; if $total_pages > 1 ) { ?>                 <div id="nav-above" class="navigation">                     <div class="nav-previous"><?php next_posts_link(__( '<span>&laquo;</span> Older posts''your-theme' )) ?></div>                     <div class="nav-next"><?php previous_posts_link(__( 'Newer posts <span>&raquo;</span>''your-theme' )) ?></div>                 </div><!-- #nav-above --> <?php } ?>
<?php /* Bottom post navigation */ ?> <?php global $wp_query$total_pages $wp_query->max_num_pages; if $total_pages > 1 ) { ?>                 <div id="nav-below" class="navigation">                     <div class="nav-previous"><?php next_posts_link(__( '<span>&laquo;</span> Older posts''your-theme' )) ?></div>                     <div class="nav-next"><?php previous_posts_link(__( 'Newer posts <span>&raquo;</span>''your-theme' )) ?></div>                 </div><!-- #nav-below --> <?php } ?>

最后一步,在 get_footer()之前写下如下代码:

1
<?php get_sidebar(); ?>

Posted on  by Ian Stewart

十一步创建一个完美wordpress主题【五】header模板

文章目录

wordpress的header模板

现在进入实质问题:创建你的header.php病使用html doctype验证你的主题。本节课会有很多php,不要害怕,我们同样要做两个基本的整洁的seo技巧和并使用function.php装扮你的主题。

现在你的空白wordpress主题在技术上还是不可行的。因为没有doctype来声明浏览器如何解析html。我们打算使用xhtml transitional doctype。当然你可以使用别的,但是xhtml transitional 对wordpress来说是最好的。

在header.php的开头输入以下内容:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 

我们也想为html添加一些其它属性。在header.php中的html标记上添加如下内容:

<html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
 

现在我们进入head标记部分,head部分包含了网页的meta信息。比如文档标题,css链接rss 订阅等。但是我们想给它加上一点功能,我们给标题加上页码。在function.php中写入

<?php
复制粘贴以下代码:
// 使主题可以被翻译
// 翻译文件可以被放置在 /languages/ 文件夹内
load_theme_textdomain( 'your-theme', TEMPLATEPATH . '/languages' );
$locale = get_locale();
$locale_file = TEMPLATEPATH . "/languages/$locale.php";
if ( is_readable($locale_file) )
        require_once($locale_file);
// 获取页码
function get_page_number() {
    if (get_query_var('paged')) {
        print ' | ' . __( 'Page ' , 'your-theme') . get_query_var('paged');
    }

}
// 获取页码结束

第一段程序意在是主题可以被翻译。

在第二段程序中,你可以看到一些可以被翻译的文本。如__( 'Page ' , 'your-theme')

你能猜到get_page_number()在干什么吗?如果你看看程序内部的话,你就会知道,它是在检查我们是不是在一个分页页面上,如果是,本程序将会打印一个分割线和当前页码。

//在解析的时候会被作为注释省略,你会看到很多。

用下面的代码替代这对标记<head></head> :

 

<head profile="http://gmpg.org/xfn/11">
    <title><?php
        if ( is_single() ) { single_post_title(); }      
        elseif ( is_home() || is_front_page() ) { bloginfo('name'); print ' | '; bloginfo('description'); get_page_number(); }
        elseif ( is_page() ) { single_post_title(''); }
        elseif ( is_search() ) { bloginfo('name'); print ' | Search results for ' . wp_specialchars($s); get_page_number(); }
        elseif ( is_404() ) { bloginfo('name'); print ' | Not Found'; }
        else { bloginfo('name'); wp_title('|'); get_page_number(); }
    ?></title>       
        <meta http-equiv="content-type" content="<?php bloginfo('html_type'); ?>; charset=<?php bloginfo('charset'); ?>" />       
        <link rel="stylesheet" type="text/css" href="<?php bloginfo('stylesheet_url'); ?>" />       
        <?php if ( is_singular() ) wp_enqueue_script( 'comment-reply' ); ?>       
        <?php wp_head(); ?>       
        <link rel="alternate" type="application/rss+xml" href="<?php bloginfo('rss2_url'); ?>" title="<?php printf( __( '%s latest posts', 'your-theme' ), wp_specialchars( get_bloginfo('name'), 1 ) ); ?>" />
        <link rel="alternate" type="application/rss+xml" href="<?php bloginfo('comments_rss2_url') ?>" title="<?php printf( __( '%s latest comments', 'your-theme' ), wp_specialchars( get_bloginfo('name'), 1 ) ); ?>" />
        <link rel="pingback" href="<?php bloginfo('pingback_url'); ?>" />      
</head>

如果你觉得这些代码像教条一样,不要紧,我会给你慢慢解释.

一个SEO的标题标签只包含单独日志或页面的标题。当然,还要通过 get_page_number() 函数显示 “较旧文章”页面的页码。

<title><?php
    if ( is_single() ) { single_post_title(); }
    elseif ( is_home() || is_front_page() ) { bloginfo('name'); print ' | '; bloginfo('description'); get_page_number(); }
    elseif ( is_page() ) { single_post_title(''); }
    elseif ( is_search() ) { bloginfo('name'); print ' | Search results for ' . wp_specialchars($s); get_page_number(); }
    elseif ( is_404() ) { bloginfo('name'); print ' | Not Found'; }
    else { bloginfo('name'); wp_title('|'); get_page_number(); }
?></title>

我们页面内容的一些meta信息:

<meta http-equiv="content-type" content="<?php bloginfo('html_type'); ?>; charset=<?php bloginfo('charset'); ?>" />

一个css链接:

1
<link rel="stylesheet" type="text/css" href="<?php bloginfo('stylesheet_url'); ?>" />

一个使用嵌套评论的脚本调用:

1
<?php if ( is_singular() ) wp_enqueue_script( 'comment-reply' ); ?>

一个插件和其它功能的钩子:

1
<?php wp_head(); ?>

RSS和pingback链接:

<link rel="alternate" type="application/rss+xml" href="<?php bloginfo('rss2_url'); ?>" title="<?php printf( __( '%s latest posts', 'your-theme' ), wp_specialchars( get_bloginfo('name'), 1 ) ); ?>" />
<link rel="alternate" type="application/rss+xml" href="<?php bloginfo('comments_rss2_url') ?>" title="<?php printf( __( '%s latest comments', 'your-theme' ), wp_specialchars( get_bloginfo('name'), 1 ) ); ?>" />
<link rel="pingback" href="<?php bloginfo('pingback_url'); ?>" />

现在我们想加入博客标题,来链接到我们的首页,博客描述,以及菜单。在header.php中移动到#branding 这个div。我们将在此处添加博客标题和描述。但是我们将做一些和其它主题不同的事情。

你会发现大部分wordpress标题告诉搜索引擎在每个页面当中最重要的是你的博客标题。他们实现这个目标的方法是使用h1标记来包装起标题部分;这个标记说明“这是本页围绕的中心”。我和其它一些主题开发者认为这是一个坏主意。举例来说,本页的最重要的东西是并不是“themeShaper”,而是“wordpress header模板”,这才是这个页面的核心内容所在。当然在首页,的确,最重要的事情是博客的描述。但从字面上它却成了本页支配一切的内容。

还好,这个很容易就能注意。我们将使用wordpress的条件标签和一些简单的旧html标记来编写我们的标题和博客描述:

            <div id="branding">
                <div id="blog-title"><span><a href="<?php bloginfo( 'url' ) ?>/" title="<?php bloginfo( 'name' ) ?>" rel="home"><?php bloginfo( 'name' ) ?></a></span></div>
<?php if ( is_home() || is_front_page() ) { ?>
                    <h1 id="blog-description"><?php bloginfo( 'description' ) ?></h1>
<?php } else { ?>
                    <div id="blog-description"><?php bloginfo( 'description' ) ?></div>
<?php } ?>
            </div><!-- #branding -->

所以,我们的链接标题被非正式的放置在一个普通的div标记里面了。我们的博客描述被放置在了一个php 的if条件标记里面,在首页他是h1,在其他页面他只是一个普通div里面的相对标题。呵呵,这样这个SEO的问题就解决了。

对于新手来讲,这个一个需要仔细研读的好地方,你需要好好研究代码才能知道到底发生了什么。在上面的代码中我们使用的wordpress的模板标签 bloginfo().你可以看到我们使用它来获得博客链接、博客名字以及博客描述。它可以 展示超过20种博客信息。明白这一点,你就明白了wordpress主题制作。我们架设一个html结构,然后向里面添加wordpress模板标签和一些php,的确是一些简单的东西。你只需要熟悉模板标签,和php if表达式,以及一些简单的php循环。

移动到#access div标记。我们将添加一个跳转链接来让那些不想看菜单想直接跳转到内容的用户得到满足。

<div class="skip-link"><a href="#content" title="<?php _e( 'Skip to content', 'your-theme' ) ?>"><?php _e( 'Skip to content', 'your-theme' ) ?></a></div>

我们添加页面菜单:

1
<?php wp_page_menu( 'sort_column=menu_order' ); ?>

简单,是吧?你的 #access div 应该是这个样子:

1
2
3
4
<div id="access">
    <div class="skip-link"><a href="#content" title="<?php _e( 'Skip to content', 'your-theme' ) ?>"><?php _e( 'Skip to content', 'your-theme' ) ?></a></div>
    <?php wp_page_menu( 'sort_column=menu_order' ); ?>
</div><!-- #access -->

就是如此,你的header.php模板就经过seo了.

Posted on  by Ian Stewart

十一步创建一个完美wordpress主题【四】模板和目录结构

本文目录

wordpress主题和目录结构

最小化的wordpress主题仅需要一个index.php模板和一个style.css文件,当然,大部分主题还需要一些其他文件来使他更加立体化。

我们的最小化主题将包含六个文件。请在你的主题文件夹下建立如下六个文件。

  • index.php
  • header.php
  • sidebar.php
  • footer.php
  • functions.php
  • style.css

首先我们在style.css内输入以下内容,来告诉wordpress我们的主题的基本信息。

/*
Theme Name: Your Theme
Theme URI: http://example.com/example/
Description: A search engine optimized website framework for WordPress.
Author: You
Author URI: http://example.com/
Version: 1.0
Tags: Comma-separated tags that describe your theme.
Your theme can be your copyrighted work.
Like WordPress, this work is released under GNU General Public License, version 2 (GPL).
http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
*/

一些需要注意的事情:其实以上内容是可选项,你可以仅仅输入你的主题名字,但是如果您想发布您的主题,那你最好认真填写以下上述内容。

废话少说,开始我们的主题制作之旅吧。

构建你的html主题结构:

让我们想一下,网页就像是讲故事,有开头,中间和结尾。当我们写index.php(当然还有之后的single.php,category.php等)的时候,我们需要把注意精力集中在中间点上,我们需要经常的重构我们的中间点,开头和结尾只需一次创建即可。

Header.php 和 Footer.php

复制以下内容到header.php:

<html>
<head>
</head>
<body>
<div id="wrapper">
    <div id="header">
        <div id="masthead">
            <div id="branding">
            </div><!-- #branding -->
            <div id="access">
            </div><!-- #access -->
        </div><!-- #masthead -->
    </div><!-- #header -->
    <div id="main">

复制以下内容到footer.php:

</div><!-- #main -->
    <div id="footer">
        <div id="colophon">
            <div id="site-info">
            </div><!-- #site-info -->
        </div><!-- #colophon -->
    </div><!-- #footer -->
</div><!-- #wrapper -->
</body>
</html>

Index.php

剩下的复制到index.php:

<div id="container">
    <div id="content">
    </div><!-- #content -->
</div><!-- #container -->
<div id="primary">
</div><!-- #primary .widget-area -->
<div id="secondary">
</div><!-- #secondary -->

在index.php上部添加以下内容:

1
<?php get_header(); ?>

在index.php底部输入以下内容:

1
<?php get_footer(); ?>

现在你可以在firefox中查看一下你的网页源代码了。

Posted on  by Ian Stewart

十一步创建一个完美wordpress主题【三】创建html基本结构

本文目录

创建wordpress主题的html结构

现在,让我们进入wordpress主题开发的实质部分,编码html结构。

任何html结构的目标

当你编写一个网站时有两个目标你必须牢记:精炼代码和有意义代码。那就是使用尽可能少的html标记并保证你的ID或者class符合语义话要求,比如使用class=”widget-area” 取代 class=”sidebar-left”。

现在,在你编写wordpress主题或者其他cms主题时,你需要保持一个平衡,既不能为了更好的结构而成为div控,也不能加入太多无意义html结构。

我们将编写可复用的html网页外观代码。

你的wordpress主题html结构

现在我们看一看我们的主题结构:

<html>
<head>
</head>

<body>
<div id="wrapper">
	<div id="header">
		<div id="masthead">

			<div id="branding">
			</div><!-- #branding -->

			<div id="access">
			</div><!-- #access -->

		</div><!-- #masthead -->
	</div><!-- #header -->

	<div id="main">
		<div id="container">

			<div id="content">
			</div><!-- #content -->

		</div><!-- #container -->

		<div id="primary">
		</div><!-- #primary .widget-area -->

		<div id="secondary">
		</div><!-- #secondary -->
	</div><!-- #main -->

	<div id="footer">
		<div id="colophon">

			<div id="site-info">
			</div><!-- #site-info -->

		</div><!-- #colophon -->
	</div><!-- #footer -->
</div><!-- #wrapper -->
</body>
</html>

将以上代码复制到你的文本编辑器,我们稍后使用它。在做这件事情之前,我们将要先看一些东西。

快速浏览你的wordpress主题html

首先,wrapper的class属性 hfeed。hfeed是 hatom Microformat schema 的一部分。浅显的讲,这就是说hfeed会告诉搜索引擎之类的东西我们发表了聚合文章,比如博客文章,之后,你会看到很多类似的class属性的命名。

看看header和footer的div结构,你可能看到了内外层次分明的结构,你甚至会会发现我们有点div控的嫌疑。我在特定的div标签上进行了语义化标记,以利于之后加上具体的wordpress对应内容。

这个结构将在你之后的开发中起到重要作用,所以请仔细阅读。

Posted on  by Ian Stewart

十一步创建一个完美wordpress主题【二】

 

本文目录

1.wordpress主题开发工具

        在我们开始构建任何wordpress主题之前,我们要先准备好我们的开发工具。本文我们将要搭建一个跨平台的专业主题制作测试环境。

2.本地测试服务器环境: XAMP or MAMP

你最好是在你的家用电脑上搭建一个具有apache、php和mysql的环境。

搭建这些软件具有一定的挑战性,幸好我们有一些集成的环境。如果你的电脑是windows,你可以试一试 XAMP. 如果你的电脑是Mac,你可以下载 MAMP 我就是采用的这个环境。

3.WordPress

安装wordpress到你的测试服务器(比如你的家用电脑)。

如果你使用xamp,请参照 instruction for installing WordPress

如果你使用 MAMP 请参照 instructions for installing WordPress

4.测试内容

你我的wordpress需要一些简单的例子文章,你可以在后台点击工具->导入,导入一些文章,如下

这里有些选项:

每种测试内容都有加有减,我的方法是导入所有的这些测试内容。这样就不会丢失任何东西。当你认为你已经完成了你的主题,使用文章导航浏览每篇文章。分别按照月、年、分类来查阅你的归档文章(archives)。拥有了这些强健的测试内容,你将会很容易的发现你丢失了什么。

5.文本编辑器

你不需要什么复杂的视窗编辑环境,仅仅是一个文本编辑器足矣.windows用户可以考虑 Notepad++. Mac用户我推荐 Text Wrangler.

6.Firefox

当然你可以使用任何浏览器测试,不过我还是推荐Firefox. 尤其是使用如下两个插件,对你开发wordpress来说更是如虎添翼。Web Developer Add-on for Firefox 为你添加了一个工具栏,通过禁用css来验证本地html,检查和调试你的代码。Firebug Add-on for Firefox 是不可缺少的. 使用firebug 你可以轻易知道当你点击网页某处时,源代码是如何编写的,以及css如何发挥作用。

7.HTML 和 CSS

我不会欺骗你,精通基本的html和css将会给你巨大的帮助。我推荐阅读html dog 的 HTML Beginner TutorialCSS Beginner Tutorial。阅读这两篇文章不是必修科目,但是它会帮助你掌握一些基本的概念。

8.PHP

在创建一个wordpress主题的时候,你需要了解php吗?是的,的确需要。但是在整个过程中,我会教会你足够小心的去开发wordpress主题。但是如果你总是想获得更多的推荐,你可以开始阅读PHP 101: PHP for the Absolute Beginner,同样不是必修课,但你会拾取些重要的概念。

十一步创建一个完美wordpress主题【一】

仅通过11wordpress主题课程就可以向您展示如何从一个草稿创建一个强大的,新式的主题。在整个过程当中,我将会解释在特定的技巧上为什么这样而不是那样。基本上,我还会告诉你开发wordpress主题你所需要知道的每件事情。


以下是你完成本主题后所值得夸耀的特性清单:

  • 你真正需要的seo。
  • 包含谷歌支持的 Microformat 标记。
  • 有效的并符合逻辑的语义结构可应用于任何页面设计。
  • 智能的默认css外观。
  • 动态的主体、文章和评论分类。
  • 独立的网站引用通告和 嵌套评论功能。
  •  两个无内容自动消失的小工具编码区域。
  • 和所有的你所期待的wordpress主体的经典功能。

我想这是对于任何wordpress主题来说都是会给人留下深刻印象的。

在本系列文章的最后,伴着手头的代码,你几乎可以做你想做的任何事情。你甚至可以考虑将完成的主题作为作为wordpress开发个人网站的框架。

我已经开始使用它启动我的另一个项目The Shape Theme。 下载它并仔细看看,如果你想看看我们将要进行的项目的最终代码的话。当然,你也可以访问最新的存放在谷歌的代码  source code for the entire tutorial 。

本文翻译自:http://themeshaper.com/2009/06/22/wordpress-themes-templates-tutorial/ 感谢作者

centos 6.2下安装配置vsftp的一个实例

一、安装vsftp,启动服务并将服务设置为自动启动

$ su - root 切换到root
# yum install vsftpd 安装vsftpd程序
# vi /etc/selinux/config  关闭selinux 确保“SELINUX=disabled”
# chkconfig --levels 345 vsftpd on 确保vsftp自动运行
# service vsftpd start  启动vsftpd

二、开放防火墙相应的端口

# vi /etc/sysconfig/iptables

添加如下内容以开放20和21端口:

-A INPUT -p tcp -m state –state NEW -m tcp –dport 20 -j ACCEPT
-A INPUT -p tcp -m state –state NEW -m tcp –dport 21 -j ACCEPT

添加如下内容设置iptables的任意端口范围:
-A INPUT -p tcp -m state --state NEW -m tcp --dport 30001:31000 -j ACCEPT
# vi /etc/vsftpd.conf
在配置文件的最下面 加入
pasv_min_port=30001
pasv_max_port=31000

三、修改默认下载路径

如果要更改默认下载目录,修改/etc/vsftpd/vsftpd.conf,加入如下三行,注意此处以改为根目录"/"为例:
local_root=/
chroot_local_user=YES
anon_root=/

四、别忘了改完后重启服务

service vsftpd restart
service iptables restart

vsftp不能访问的iptables设置

因为FTP的端口是 两个,一个是固定21端口,还有一个任意端口的数据通道。关键是任意端口不好搞。

首先在vsftpd的配置文件中设置 任意端口的范围

[root@localhost root]# vi /etc/vsftpd.conf
在配置文件的最下面 加入
pasv_min_port=30001
pasv_max_port=31000
然后保存退出。

然后设置iptables防火墙的配置文件

[root@localhost root]# vi /etc/sysconfig/iptables
在配置文件的最下面 加入

-A INPUT -p tcp -m state –state NEW -m tcp –dport 30001:31000 -j ACCEPT

然后保存退出。

 

lvm新手指南(七)

之后,我将md0和md1创建pv,并加入到lvm:

server1:~# pvcreate /dev/md0 /dev/md1

Physical volume ”/dev/md0″ successfully created
Physical volume ”/dev/md1″ successfully created

扩展vg:

server1:~# vgextend fileserver /dev/md0 /dev/md1

Volume group ”fileserver” successfully extended

server1:~# pvdisplay

— Physical volume —
PV Name               /dev/sdb1
VG Name               fileserver
PV Size               23.29 GB / not usable 0
Allocatable           yes (but full)
PE Size (KByte)       4096
Total PE              5961
Free PE               0
Allocated PE          5961
PV UUID               USDJyG-VDM2-r406-OjQo-h3eb-c9Mp-4nvnvu

— Physical volume —
PV Name               /dev/sdd1
VG Name               fileserver
PV Size               23.29 GB / not usable 0
Allocatable           yes
PE Size (KByte)       4096
Total PE              5961
Free PE               146
Allocated PE          5815
PV UUID               qdEB5d-389d-O5UA-Kbwv-mn1y-74FY-4zublN

— Physical volume —
PV Name               /dev/md0
VG Name               fileserver
PV Size               23.29 GB / not usable 0
Allocatable           yes
PE Size (KByte)       4096
Total PE              5961
Free PE               5961
Allocated PE          0
PV UUID               7JHUXF-1R2p-OjbJ-X1OT-uaeg-gWRx-H6zx3P

— Physical volume —
PV Name               /dev/md1
VG Name               fileserver
PV Size               23.29 GB / not usable 0
Allocatable           yes
PE Size (KByte)       4096
Total PE              5961
Free PE               5961
Allocated PE          0
PV UUID               pwQ5AJ-RwVK-EebA-0Z13-d27d-2IdP-HqT5RW

server1:~# vgdisplay
— Volume group —
VG Name               fileserver
System ID
Format                lvm2
Metadata Areas        4
Metadata Sequence No  14
VG Access             read/write
VG Status             resizable
MAX LV                0
Cur LV                3
Open LV               3
Max PV                0
Cur PV                4
Act PV                4
VG Size               93.14 GB
PE Size               4.00 MB
Total PE              23844
Alloc PE / Size       11776 / 46.00 GB
Free  PE / Size       12068 / 47.14 GB
VG UUID               dQDEHT-kNHf-UjRm-rmJ3-OUYx-9G1t-aVskI1

现在,我们将sdb1的内容转移到md0,将sdd1的内容转移到md1,并卸载这两个分区:

pvmove /dev/sdb1 /dev/md0
pvmove /dev/sdd1 /dev/md1
vgreduce fileserver /dev/sdb1 /dev/sdd1
 pvremove /dev/sdb1 /dev/sdd1

server1:~# pvdisplay

— Physical volume —
PV Name               /dev/md0
VG Name               fileserver
PV Size               23.29 GB / not usable 0
Allocatable           yes (but full)
PE Size (KByte)       4096
Total PE              5961
Free PE               0
Allocated PE          5961
PV UUID               7JHUXF-1R2p-OjbJ-X1OT-uaeg-gWRx-H6zx3P

— Physical volume —
PV Name               /dev/md1
VG Name               fileserver
PV Size               23.29 GB / not usable 0
Allocatable           yes
PE Size (KByte)       4096
Total PE              5961
Free PE               146
Allocated PE          5815
PV UUID               pwQ5AJ-RwVK-EebA-0Z13-d27d-2IdP-HqT5RW

格式化sdb为fd(raid)格式:

server1:~# fdisk /dev/sdb

The number of cylinders for this disk is set to 32635.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
(e.g., DOS FDISK, OS/2 FDISK)

Command (m for help): <– m
Command action
a   toggle a bootable flag
b   edit bsd disklabel
c   toggle the dos compatibility flag
d   delete a partition
l   list known partition types
m   print this menu
n   add a new partition
o   create a new empty DOS partition table
p   print the partition table
q   quit without saving changes
s   create a new empty Sun disklabel
t   change a partition’s system id
u   change display/entry units
v   verify the partition table
w   write table to disk and exit
x   extra functionality (experts only)

Command (m for help): <– t
Selected partition 1
Hex code (type L to list codes): <– fd
Changed system type of partition 1 to fd (Linux raid autodetect)

Command (m for help): <– w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

同样的方式处理sdd:

fdisk /dev/sdd

现在将sdb1加到md0,将sdd1加到md1:

server1:~# mdadm –manage /dev/md0 –add /dev/sdb1

mdadm: added /dev/sdb1

server1:~# mdadm –manage /dev/md1 –add /dev/sdd1

mdadm: added /dev/sdd1

现在磁盘将开始同步,你可以查看同步过程详情:

cat /proc/mdstat

同步情况如下:

server1:~# cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid5] [raid4] [raid6] [raid10]
md1 : active raid1 sdd1[2] sde1[0]
24418688 blocks [2/1] [U_]
[=>...................]  recovery =  6.4% (1586560/24418688) finish=1.9min speed=198320K/sec

md0 : active raid1 sdb1[2] sdc1[0]
24418688 blocks [2/1] [U_]
[==>..................]  recovery = 10.5% (2587264/24418688) finish=2.8min speed=129363K/sec

unused devices: <none>

完成后如下:

server1:~# cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid5] [raid4] [raid6] [raid10]
md1 : active raid1 sdd1[1] sde1[0]
24418688 blocks [2/2] [UU]

md0 : active raid1 sdb1[1] sdc1[0]
24418688 blocks [2/2] [UU]

unused devices: <none>

看一下pv:

你会看到2*23.29GB=46,58GB是可用的,但是你的三个lv只是用了40+5+1=46G,所以这意味着你可以扩展你的lv大约0.5G的空间,我已经展示过如何扩展ext3的lv分区(share),现在,我将展示reiserfs在不卸载情况下如何调整大小。

server1:~# lvextend -L1.5G /dev/fileserver/media
Extending logical volume media to 1.50 GB
Logical volume media successfully resized

server1:~# resize_reiserfs /dev/fileserver/media

resize_reiserfs 3.6.19 (2003 www.namesys.com)

resize_reiserfs: On-line resizing finished successfully.

server1:~# df -h

Filesystem            Size  Used Avail Use% Mounted on
/dev/sda2              19G  666M   17G   4% /
tmpfs                  78M     0   78M   0% /lib/init/rw
udev                   10M   92K   10M   1% /dev
tmpfs                  78M     0   78M   0% /dev/shm
/dev/sda1             137M   17M  114M  13% /boot
/dev/mapper/fileserver-share
40G  177M   38G   1% /var/share
/dev/mapper/fileserver-backup
5.0G  144K  5.0G   1% /var/backup
/dev/mapper/fileserver-media
1.5G   33M  1.5G   3% /var/media

想要自动挂载我们的lv,只需要再一次修改一下我们的/etc/fstab文件就OK:

mv /etc/fstab /etc/fstab_orig
 cat /dev/null > /etc/fstab
vi /etc/fstab

加上这些内容:

# /etc/fstab: static file system information.
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
proc            /proc           proc    defaults        0       0
/dev/sda2       /               ext3    defaults,errors=remount-ro 0       1
/dev/sda1       /boot           ext3    defaults        0       2
/dev/hdc        /media/cdrom0   udf,iso9660 user,noauto     0       0
/dev/fd0        /media/floppy0  auto    rw,user,noauto  0       0
/dev/fileserver/share   /var/share     ext3       rw,noatime    0 0
/dev/fileserver/backup    /var/backup      xfs        rw,noatime    0 0
/dev/fileserver/media    /var/media      reiserfs   rw,noatime    0 0

对比一下,实际添加了如下内容:

/dev/fileserver/share   /var/share     ext3       rw,noatime    0 0
/dev/fileserver/backup    /var/backup      xfs        rw,noatime    0 0
/dev/fileserver/media    /var/media      reiserfs   rw,noatime    0 0

重启系统,查看信息如下:

server1:~# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda2              19G  666M   17G   4% /
tmpfs                  78M     0   78M   0% /lib/init/rw
udev                   10M  100K   10M   1% /dev
tmpfs                  78M     0   78M   0% /dev/shm
/dev/sda1             137M   17M  114M  13% /boot
/dev/mapper/fileserver-share
40G  177M   38G   1% /var/share
/dev/mapper/fileserver-backup
5.0G  144K  5.0G   1% /var/backup
/dev/mapper/fileserver-media
1.5G   33M  1.5G   3% /var/media

至此:lvm上的raid1安装完毕。

本文由www.iluther.net翻译(原文在howtoforge),转载请注明出处

lvm新手指南(六)

6 恢复到系统初始状态

本小节我们将会把所作的改动都撤销,恢复到系统的初始状态,这仅仅是为了让您学会怎样撤销一个lvm的安装过程。

首先写在三个lv:

umount /var/share
umount /var/backup
umount /var/media

df -h

server1:~# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda2              19G  665M   17G   4% /
tmpfs                  78M     0   78M   0% /lib/init/rw
udev                   10M   92K   10M   1% /dev
tmpfs                  78M     0   78M   0% /dev/shm
/dev/sda1             137M   17M  114M  13% /boot

删除lv:

lvremove /dev/fileserver/share

server1:~# lvremove /dev/fileserver/share
Do you really want to remove active logical volume ”share”? [y/n]: <– y
Logical volume ”share” successfully removed

lvremove /dev/fileserver/backup

server1:~# lvremove /dev/fileserver/backup
Do you really want to remove active logical volume ”backup”? [y/n]: <– y
Logical volume ”backup” successfully removed

lvremove /dev/fileserver/media

server1:~# lvremove /dev/fileserver/media
Do you really want to remove active logical volume ”media”? [y/n]: <– y
Logical volume ”media” successfully removed

删除 vg:

vgremove fileserver

server1:~# vgremove fileserver
Volume group ”fileserver” successfully removed

最后删除pv:

pvremove /dev/sdc1 /dev/sdd1 /dev/sde1 /dev/sdf1

server1:~# pvremove  /dev/sdc1 /dev/sdd1 /dev/sde1 /dev/sdf1
Labels on physical volume ”/dev/sdc1″ successfully wiped
Labels on physical volume ”/dev/sdd1″ successfully wiped
Labels on physical volume ”/dev/sde1″ successfully wiped
Labels on physical volume ”/dev/sdf1″ successfully wiped

vgdisplay

server1:~# vgdisplay
No volume groups found

pvdisplay

server1:~# pvdisplay

恢复/etc/fstab:让系统不在试图挂在不存在的设备,我们只需要把之前备份的fstab文件恢复回来即可。

mv /etc/fstab_orig /etc/fstab

重启系统:

shutdown -r now

查看系统状态:现在又恢复如初了。

server1:~# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda2              19G  666M   17G   4% /
tmpfs                  78M     0   78M   0% /lib/init/rw
udev                   10M   92K   10M   1% /dev
tmpfs                  78M     0   78M   0% /dev/shm
/dev/sda1             137M   17M  114M  13% /boot

此时系统基本恢复如初,但是分区/dev/sdb1 - /dev/sdf1 还在, – 你可以使用fdisk命令将他们删除,但是现在我们不这样做,同时我们也保留这几个目录,以备接下来使用: /var/share, /var/backup, and /var/media 。

 

7 创建RAID1上的lvm

本节,我们创建再一次创建lvm,并将它架设在raid1上来保证高可用性。最终效果如下:

这意味着我们将要使用sdb1和sdc1创建md0  raid阵列,使用sdd1和sdfe1创建md1 raid阵列,md0和md1这两个raid阵列将作为pv来建构lvm fileserver。(结构如上图)

在做这个任务之前,我们先像之前那样创建lvm:

pvcreate /dev/sdb1 /dev/sdc1 /dev/sdd1 /dev/sde1
 vgcreate fileserver /dev/sdb1 /dev/sdc1 /dev/sdd1 /dev/sde1
 lvcreate --name share --size 40G fileserver
 lvcreate --name backup --size 5G fileserver
 lvcreate --name media --size 1G fileserver
mkfs.ext3 /dev/fileserver/share
 mkfs.xfs /dev/fileserver/backup
 mkfs.reiserfs /dev/fileserver/media
mount /dev/fileserver/share /var/share
 mount /dev/fileserver/backup /var/backup
 mount /dev/fileserver/media /var/media

看一下输出结果:

server1:~# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda2              19G  666M   17G   4% /
tmpfs                  78M     0   78M   0% /lib/init/rw
udev                   10M   92K   10M   1% /dev
tmpfs                  78M     0   78M   0% /dev/shm
/dev/sda1             137M   17M  114M  13% /boot
/dev/mapper/fileserver-share
40G  177M   38G   1% /var/share
/dev/mapper/fileserver-backup
5.0G  144K  5.0G   1% /var/backup
/dev/mapper/fileserver-media
1.0G   33M  992M   4% /var/media

首先我们先备份要移走的分区的数据:把sdc1和sde1的数据移动到sdb1和sdd1。然后把sdc1和sde1从lvm中移走,然后把他们格式化成为fd格式(raid的格式),并且把它们分别添加到raid md0和md1中。

modprobe dm-mirror
 pvmove /dev/sdc1
vgreduce fileserver /dev/sdc1
 pvremove /dev/sdc1

server1:~# pvdisplay

— Physical volume —
PV Name               /dev/sdb1
VG Name               fileserver
PV Size               23.29 GB / not usable 0
Allocatable           yes (but full)
PE Size (KByte)       4096
Total PE              5961
Free PE               0
Allocated PE          5961
PV UUID               USDJyG-VDM2-r406-OjQo-h3eb-c9Mp-4nvnvu

— Physical volume —
PV Name               /dev/sdd1
VG Name               fileserver
PV Size               23.29 GB / not usable 0
Allocatable           yes
PE Size (KByte)       4096
Total PE              5961
Free PE               4681
Allocated PE          1280
PV UUID               qdEB5d-389d-O5UA-Kbwv-mn1y-74FY-4zublN

— Physical volume —
PV Name               /dev/sde1
VG Name               fileserver
PV Size               23.29 GB / not usable 0
Allocatable           yes
PE Size (KByte)       4096
Total PE              5961
Free PE               1426
Allocated PE          4535
PV UUID               4vL1e0-sr2M-awGd-qDJm-ZrC9-wuxW-2lEqp2

pvmove /dev/sde1
vgreduce fileserver /dev/sde1
 pvremove /dev/sde1

server1:~# pvdisplay

— Physical volume —
PV Name               /dev/sdb1
VG Name               fileserver
PV Size               23.29 GB / not usable 0
Allocatable           yes (but full)
PE Size (KByte)       4096
Total PE              5961
Free PE               0
Allocated PE          5961
PV UUID               USDJyG-VDM2-r406-OjQo-h3eb-c9Mp-4nvnvu

— Physical volume —
PV Name               /dev/sdd1
VG Name               fileserver
PV Size               23.29 GB / not usable 0
Allocatable           yes
PE Size (KByte)       4096
Total PE              5961
Free PE               146
Allocated PE          5815
PV UUID               qdEB5d-389d-O5UA-Kbwv-mn1y-74FY-4zublN

将sdc变成fd(raid)格式

fdisk /dev/sdc

server1:~# fdisk /dev/sdc

The number of cylinders for this disk is set to 10443.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
(e.g., DOS FDISK, OS/2 FDISK)

Command (m for help): <– m
Command action
a   toggle a bootable flag
b   edit bsd disklabel
c   toggle the dos compatibility flag
d   delete a partition
l   list known partition types
m   print this menu
n   add a new partition
o   create a new empty DOS partition table
p   print the partition table
q   quit without saving changes
s   create a new empty Sun disklabel
t   change a partition’s system id
u   change display/entry units
v   verify the partition table
w   write table to disk and exit
x   extra functionality (experts only)

Command (m for help): <– t
Selected partition 1
Hex code (type L to list codes): <– L

0  Empty           1e  Hidden W95 FAT1 80  Old Minix       be  Solaris boot
1  FAT12           24  NEC DOS         81  Minix / old Lin bf  Solaris
2  XENIX root      39  Plan 9          82  Linux swap / So c1  DRDOS/sec (FAT-
3  XENIX usr       3c  PartitionMagic  83  Linux           c4  DRDOS/sec (FAT-
4  FAT16 <32M      40  Venix 80286     84  OS/2 hidden C:  c6  DRDOS/sec (FAT-
5  Extended        41  PPC PReP Boot   85  Linux extended  c7  Syrinx
6  FAT16           42  SFS             86  NTFS volume set da  Non-FS data
7  HPFS/NTFS       4d  QNX4.x          87  NTFS volume set db  CP/M / CTOS / .
8  AIX             4e  QNX4.x 2nd part 88  Linux plaintext de  Dell Utility
9  AIX bootable    4f  QNX4.x 3rd part 8e  Linux LVM       df  BootIt
a  OS/2 Boot Manag 50  OnTrack DM      93  Amoeba          e1  DOS access
b  W95 FAT32       51  OnTrack DM6 Aux 94  Amoeba BBT      e3  DOS R/O
c  W95 FAT32 (LBA) 52  CP/M            9f  BSD/OS          e4  SpeedStor
e  W95 FAT16 (LBA) 53  OnTrack DM6 Aux a0  IBM Thinkpad hi eb  BeOS fs
f  W95 Ext’d (LBA) 54  OnTrackDM6      a5  FreeBSD         ee  EFI GPT
10  OPUS            55  EZ-Drive        a6  OpenBSD         ef  EFI (FAT-12/16/
11  Hidden FAT12    56  Golden Bow      a7  NeXTSTEP        f0  Linux/PA-RISC b
12  Compaq diagnost 5c  Priam Edisk     a8  Darwin UFS      f1  SpeedStor
14  Hidden FAT16 <3 61  SpeedStor       a9  NetBSD          f4  SpeedStor
16  Hidden FAT16    63  GNU HURD or Sys ab  Darwin boot     f2  DOS secondary
17  Hidden HPFS/NTF 64  Novell Netware  b7  BSDI fs         fd  Linux raid auto
18  AST SmartSleep  65  Novell Netware  b8  BSDI swap       fe  LANstep
1b  Hidden W95 FAT3 70  DiskSecure Mult bb  Boot Wizard hid ff  BBT
1c  Hidden W95 FAT3 75  PC/IX
Hex code (type L to list codes): <– fd
Changed system type of partition 1 to fd (Linux raid autodetect)

Command (m for help): <– w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

sde也是一样:

fdisk /dev/sde

server1:~# fdisk -l

Disk /dev/sda: 21.4 GB, 21474836480 bytes
255 heads, 63 sectors/track, 2610 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          18      144553+  83  Linux
/dev/sda2              19        2450    19535040   83  Linux
/dev/sda4            2451        2610     1285200   82  Linux swap / Solaris

Disk /dev/sdb: 85.8 GB, 85899345920 bytes
255 heads, 63 sectors/track, 10443 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1        3040    24418768+  8e  Linux LVM

Disk /dev/sdc: 85.8 GB, 85899345920 bytes
255 heads, 63 sectors/track, 10443 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Device Boot      Start         End      Blocks   Id  System
/dev/sdc1               1        3040    24418768+  fd  Linux raid autodetect

Disk /dev/sdd: 85.8 GB, 85899345920 bytes
255 heads, 63 sectors/track, 10443 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Device Boot      Start         End      Blocks   Id  System
/dev/sdd1               1        3040    24418768+  8e  Linux LVM

Disk /dev/sde: 85.8 GB, 85899345920 bytes
255 heads, 63 sectors/track, 10443 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Device Boot      Start         End      Blocks   Id  System
/dev/sde1               1        3040    24418768+  fd  Linux raid autodetect

Disk /dev/sdf: 85.8 GB, 85899345920 bytes
255 heads, 63 sectors/track, 10443 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

Device Boot      Start         End      Blocks   Id  System
/dev/sdf1               1        3040    24418768+  8e  Linux LVM

现在我们将sdc1添加到md0,将sde1添加到md1,因为sdb1和sdd1还没有准备好,所以我们要在命令的末尾加上:missing

Next we add /dev/sdc1 to /dev/md0 and /dev/sde1 to /dev/md1. Because the second nodes (/dev/sdb1 and /dev/sdd1) are not ready yet, we must specifymissing in the following commands:

mdadm --create /dev/md0 --auto=yes -l 1 -n 2 /dev/sdc1 missing

server1:~# mdadm –create /dev/md0 –auto=yes -l 1 -n 2 /dev/sdc1 missing
mdadm: array /dev/md0 started.

mdadm --create /dev/md1 --auto=yes -l 1 -n 2 /dev/sde1 missing

server1:~# mdadm –create /dev/md1 –auto=yes -l 1 -n 2 /dev/sde1 missing
mdadm: array /dev/md1 started.

本文由www.iluther.net翻译(原文在howtoforge),转载请注明出处

lvm新手指南(五)

5 添加一个硬盘,移走另一个硬盘

至今,我们还没有使用/dev/sdf这个磁盘,现在我们就创建分区 /dev/sdf1(25GB)并且把它添加到我们的vg fileserver里面。

fdisk /dev/sdf

server1:~# fdisk /dev/sdf
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel. Changes will remain in memory only,
until you decide to write them. After that, of course, the previous
content won’t be recoverable.

The number of cylinders for this disk is set to 10443.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
(e.g., DOS FDISK, OS/2 FDISK)
Warning: invalid flag 0×0000 of partition table 4 will be corrected by w(rite)

Command (m for help): <– m
Command action
a   toggle a bootable flag
b   edit bsd disklabel
c   toggle the dos compatibility flag
d   delete a partition
l   list known partition types
m   print this menu
n   add a new partition
o   create a new empty DOS partition table
p   print the partition table
q   quit without saving changes
s   create a new empty Sun disklabel
t   change a partition’s system id
u   change display/entry units
v   verify the partition table
w   write table to disk and exit
x   extra functionality (experts only)

Command (m for help): <– n
Command action
e   extended
p   primary partition (1-4)
<– p
Partition number (1-4): <– 1
First cylinder (1-10443, default 1):
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-10443, default 10443): <– +25000M

Command (m for help): <– t
Selected partition 1
Hex code (type L to list codes): <– 8e
Changed system type of partition 1 to 8e (Linux LVM)

Command (m for help): <– w
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

创建pv,为lvm做准备:

pvcreate /dev/sdf1

server1:~# pvcreate /dev/sdf1
Physical volume ”/dev/sdf1″ successfully created

将 /dev/sdf1 添加到我们的vg  fileserver里。

vgextend fileserver /dev/sdf1

查看vg:

server1:~# vgdisplay
— Volume group —
VG Name               fileserver
System ID
Format                lvm2
Metadata Areas        5
Metadata Sequence No  12
VG Access             read/write
VG Status             resizable
MAX LV                0
Cur LV                3
Open LV               3
Max PV                0
Cur PV                5
Act PV                5
VG Size               116.43 GB
PE Size               4.00 MB
Total PE              29805
Alloc PE / Size       11776 / 46.00 GB
Free  PE / Size       18029 / 70.43 GB
VG UUID               iWr1Vk-7h7J-hLRL-SHbx-3p87-Rq47-L1GyEO

此时可以看到添加成功:

现在我们需要移走/dev/sdb1,移走之前,我们需要所上面的所有数据拷贝到/dev/sdf1:

pvmove /dev/sdb1 /dev/sdf1

几分钟后即可结束,看数据量的大小。

server1:~# pvmove /dev/sdb1 /dev/sdf1
/dev/sdb1: Moved: 1.9%
/dev/sdb1: Moved: 3.8%
/dev/sdb1: Moved: 5.8%
/dev/sdb1: Moved: 7.8%
/dev/sdb1: Moved: 9.7%
/dev/sdb1: Moved: 11.6%
/dev/sdb1: Moved: 13.6%
/dev/sdb1: Moved: 15.6%
/dev/sdb1: Moved: 17.5%
/dev/sdb1: Moved: 19.4%
/dev/sdb1: Moved: 21.4%
[...]
/dev/sdb1: Moved: 85.7%
/dev/sdb1: Moved: 87.7%
/dev/sdb1: Moved: 89.7%
/dev/sdb1: Moved: 91.7%
/dev/sdb1: Moved: 93.6%
/dev/sdb1: Moved: 95.5%
/dev/sdb1: Moved: 97.5%
/dev/sdb1: Moved: 99.4%
/dev/sdb1: Moved: 100.0%

现在我们可以把/dev/sdb1移走。

vgreduce fileserver /dev/sdb1

server1:~# vgreduce fileserver /dev/sdb1
Removed ”/dev/sdb1″ from volume group ”fileserver”

vgdisplay

server1:~# vgdisplay
— Volume group —
VG Name               fileserver
System ID
Format                lvm2
Metadata Areas        4
Metadata Sequence No  16
VG Access             read/write
VG Status             resizable
MAX LV                0
Cur LV                3
Open LV               3
Max PV                0
Cur PV                4
Act PV                4
VG Size               93.14 GB
PE Size               4.00 MB
Total PE              23844
Alloc PE / Size       11776 / 46.00 GB
Free  PE / Size       12068 / 47.14 GB
VG UUID               iWr1Vk-7h7J-hLRL-SHbx-3p87-Rq47-L1GyEO

再移走pv:

pvremove /dev/sdb1

查看结果:

pvdisplay

server1:~# pvdisplay
— Physical volume —
PV Name               /dev/sdc1
VG Name               fileserver
PV Size               23.29 GB / not usable 0
Allocatable           yes
PE Size (KByte)       4096
Total PE              5961
Free PE               1682
Allocated PE          4279
PV UUID               40GJyh-IbsI-pzhn-TDRq-PQ3l-3ut0-AVSE4B

— Physical volume —
PV Name               /dev/sdd1
VG Name               fileserver
PV Size               23.29 GB / not usable 0
Allocatable           yes
PE Size (KByte)       4096
Total PE              5961
Free PE               4681
Allocated PE          1280
PV UUID               4mU63D-4s26-uL00-r0pO-Q0hP-mvQR-2YJN5B

— Physical volume —
PV Name               /dev/sde1
VG Name               fileserver
PV Size               23.29 GB / not usable 0
Allocatable           yes
PE Size (KByte)       4096
Total PE              5961
Free PE               5705
Allocated PE          256
PV UUID               3upcZc-4eS2-h4r4-iBKK-gZJv-AYt3-EKdRK6

— Physical volume —
PV Name               /dev/sdf1
VG Name               fileserver
PV Size               23.29 GB / not usable 0
Allocatable           yes (but full)
PE Size (KByte)       4096
Total PE              5961
Free PE               0
Allocated PE          5961
PV UUID               1xgo2I-SBjj-0MAz-lmDu-OLZ1-3NdO-mLkS20

如果是一个实体机器(而非虚拟机)的话,现在你就可以把硬盘sdb拔下,拿走了!

本文由www.iluther.net翻译(原文在howtoforge),转载请注明出处

lvm新手指南(四)

4 调整lv和他们的文件系统

在本节中我们将要学习如何调整share这个含有ext3文件系统的lv的大小。(之后,我将演示调整含有xfs和reiserfs文件系统的lv的大小。

首先卸载lv:

umount /var/share

查看挂载信息:

server1:~# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda2              19G  665M   17G   4% /
tmpfs                  78M     0   78M   0% /lib/init/rw
udev                   10M   88K   10M   1% /dev
tmpfs                  78M     0   78M   0% /dev/shm
/dev/sda1             137M   17M  114M  13% /boot
/dev/mapper/fileserver-backup
5.0G  144K  5.0G   1% /var/backup
/dev/mapper/fileserver-media
1.0G   33M  992M   4% /var/media

现在我们把share这个lv从40GB增大到50GB:

lvextend -L50G /dev/fileserver/share

server1:~# lvextend -L50G /dev/fileserver/share
Extending logical volume share to 50.00 GB
Logical volume share successfully resized

截至到目前,我们仅仅增大了share这个lv,并没有把share上的ext3文件系统的大小信息改变,因此我们需要:

e2fsck -f /dev/fileserver/share

server1:~# e2fsck -f /dev/fileserver/share
e2fsck 1.40-WIP (14-Nov-2006)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/fileserver/share: 11/5242880 files (9.1% non-contiguous), 209588/10485760 blocks

记下这个块数量信息 (10485760) ,因为一会我们做缩回实验需要这个数值.

resize2fs /dev/fileserver/share

server1:~# resize2fs /dev/fileserver/share
resize2fs 1.40-WIP (14-Nov-2006)
Resizing the filesystem on /dev/fileserver/share to 13107200 (4k) blocks.
The filesystem on /dev/fileserver/share is now 13107200 blocks long.

重新挂载share:

mount /dev/fileserver/share /var/share

重新查看,share由40G变成了50G:

server1:~# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda2              19G  665M   17G   4% /
tmpfs                  78M     0   78M   0% /lib/init/rw
udev                   10M   88K   10M   1% /dev
tmpfs                  78M     0   78M   0% /dev/shm
/dev/sda1             137M   17M  114M  13% /boot
/dev/mapper/fileserver-backup
5.0G  144K  5.0G   1% /var/backup
/dev/mapper/fileserver-media
1.0G   33M  992M   4% /var/media
/dev/mapper/fileserver-share
50G  180M   47G   1% /var/share

缩回命令正好和扩展命令相反,首先我们先收缩文件系统的大小,然后再收缩lv的大小,好,让我们把50G的share再缩回到40G大小:

首先卸载share:

umount /var/share

插看:

server1:~# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda2              19G  665M   17G   4% /
tmpfs                  78M     0   78M   0% /lib/init/rw
udev                   10M   88K   10M   1% /dev
tmpfs                  78M     0   78M   0% /dev/shm
/dev/sda1             137M   17M  114M  13% /boot
/dev/mapper/fileserver-backup
5.0G  144K  5.0G   1% /var/backup
/dev/mapper/fileserver-media
1.0G   33M  992M   4% /var/media

看share这个lv的文件系统信息:

e2fsck -f /dev/fileserver/share

server1:~# e2fsck -f /dev/fileserver/share
e2fsck 1.40-WIP (14-Nov-2006)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/fileserver/share: 11/6553600 files (9.1% non-contiguous), 251733/13107200 blocks

当我们要把ext3文件系统的大小调整到一个具体的值的时候,这个值需要是磁盘“块数(number of blocks)”,(你可以调整到具体的MB数,可以man一下resize2fs这个命令以获取更多详细信息,)在之前的操作中,我们知道40G=1048560blocks,所以我们执行:

resize2fs /dev/fileserver/share 10485760

server1:~# resize2fs /dev/fileserver/share 10485760
resize2fs 1.40-WIP (14-Nov-2006)
Resizing the filesystem on /dev/fileserver/share to 10485760 (4k) blocks.
The filesystem on /dev/fileserver/share is now 10485760 blocks long.

我们已经收缩了文件系统,下面我们收缩lv:

lvreduce -L40G /dev/fileserver/share

server1:~# lvreduce -L40G /dev/fileserver/share
WARNING: Reducing active logical volume to 40.00 GB
THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce share? [y/n]: <– y
Reducing logical volume share to 40.00 GB
Logical volume share successfully resized

我们可以忽略告警,因为我们已经调整好了文件系统的大小

重新挂载:

查看信息:

server1:~# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda2              19G  665M   17G   4% /
tmpfs                  78M     0   78M   0% /lib/init/rw
udev                   10M   88K   10M   1% /dev
tmpfs                  78M     0   78M   0% /dev/shm
/dev/sda1             137M   17M  114M  13% /boot
/dev/mapper/fileserver-backup
5.0G  144K  5.0G   1% /var/backup
/dev/mapper/fileserver-media
1.0G   33M  992M   4% /var/media
/dev/mapper/fileserver-share
40G  177M   38G   1% /var/share

本文由www.iluther.net翻译(原文在howtoforge),转载请注明出处

lvm新手指南(三)

到目前为止,我们已经拥有了三个lv(逻辑卷logical volume),但是它们都没有文件系统,所以不能存储任何东西。因此我们打算在share中ext3文件系统,在backup中创建xfs文件系统,在media中创建reiserfs文件系统:

mkfs.ext3 /dev/fileserver/share

server1:~# mkfs.ext3 /dev/fileserver/share
mke2fs 1.40-WIP (14-Nov-2006)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
5242880 inodes, 10485760 blocks
524288 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=0
320 block groups
32768 blocks per group, 32768 fragments per group
16384 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624

Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 23 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.

mkfs.xfs /dev/fileserver/backup

server1:~# mkfs.xfs /dev/fileserver/backup
meta-data=/dev/fileserver/backup isize=256    agcount=8, agsize=163840 blks
=                       sectsz=512   attr=0
data     =                       bsize=4096   blocks=1310720, imaxpct=25
=                       sunit=0      swidth=0 blks, unwritten=1
naming   =version 2              bsize=4096
log      =internal log           bsize=4096   blocks=2560, version=1
=                       sectsz=512   sunit=0 blks
realtime =none                   extsz=65536  blocks=0, rtextents=0

mkfs.reiserfs /dev/fileserver/media

server1:~# mkfs.reiserfs /dev/fileserver/media
mkfs.reiserfs 3.6.19 (2003 www.namesys.com)

A pair of credits:
Alexander  Lyamin  keeps our hardware  running,  and was very  generous  to our
project in many little ways.

Chris Mason wrote the journaling code for V3,  which was enormously more useful
to users than just waiting until  we could create a wandering log filesystem as
Hans would have unwisely done without him.
Jeff Mahoney optimized the bitmap  scanning code for V3,  and performed the big
endian cleanups.

Guessing about desired format.. Kernel 2.6.17-2-486 is running.
Format 3.6 with standard journal
Count of blocks on the device: 262144
Number of blocks consumed by mkreiserfs formatting process: 8219
Blocksize: 4096
Hash function used to sort names: ”r5″
Journal Size 8193 blocks (first block 18)
Journal Max transaction length 1024
inode generation number: 0
UUID: 2bebf750-6e05-47b2-99b6-916fa7ea5398
ATTENTION: YOU SHOULD REBOOT AFTER FDISK!
ALL DATA WILL BE LOST ON ’/dev/fileserver/media’!
Continue (y/n):y
Initializing journal - 0%….20%….40%….60%….80%….100%
Syncing..ok

Tell your friends to use a kernel based on 2.4.18 or later, and especially not a
kernel based on 2.4.9, when you use reiserFS. Have fun.

ReiserFS is successfully created on /dev/fileserver/media.

以上三个lv经过以上步骤被成功配置了文件系统,接下来我们准备挂载我们的lv,配置如下:

share 挂载在 /var/share, backup 挂载在 /var/backup, media 挂载在/var/media,因此我们需要先创建三个文件夹:

mkdir /var/media /var/backup /var/share

现在我们挂载lv:

mount /dev/fileserver/share /var/share
mount /dev/fileserver/backup /var/backup
mount /dev/fileserver/media /var/media

查看信息:

server1:~# df -h

Filesystem            Size  Used Avail Use% Mounted on
/dev/sda2              19G  665M   17G   4% /
tmpfs                  78M     0   78M   0% /lib/init/rw
udev                   10M   88K   10M   1% /dev
tmpfs                  78M     0   78M   0% /dev/shm
/dev/sda1             137M   17M  114M  13% /boot
/dev/mapper/fileserver-share
40G  177M   38G   1% /var/share
/dev/mapper/fileserver-backup
5.0G  144K  5.0G   1% /var/backup
/dev/mapper/fileserver-media
1.0G   33M  992M   4% /var/media

恭喜你,你已经成功创建了你的第一个lvm系统,你可以在如下三个位置随意读写 /var/share, /var/backup, and /var/media 。

我们已经手动挂载了这三个lv,我们当然希望系统每次启动自动挂载. 因此我们需要修改 /etc/fstab:

mv /etc/fstab /etc/fstab_orig
cat /dev/null > /etc/fstab

vi /etc/fstab

输入以下信息:

# /etc/fstab: static file system information.
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
proc            /proc           proc    defaults        0       0
/dev/sda2       /               ext3    defaults,errors=remount-ro 0       1
/dev/sda1       /boot           ext3    defaults        0       2
/dev/hdc        /media/cdrom0   udf,iso9660 user,noauto     0       0
/dev/fd0        /media/floppy0  auto    rw,user,noauto  0       0
/dev/fileserver/share   /var/share     ext3       rw,noatime    0 0
/dev/fileserver/backup    /var/backup      xfs        rw,noatime    0 0
/dev/fileserver/media    /var/media      reiserfs   rw,noatime    0 0

和我们备份的fstab对比以下,你会发现增加了如下内容:

/dev/fileserver/share   /var/share     ext3       rw,noatime    0 0
/dev/fileserver/backup    /var/backup      xfs        rw,noatime    0 0
/dev/fileserver/media    /var/media      reiserfs   rw,noatime    0 0

重启系统看一下:

server1:~# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda2              19G  665M   17G   4% /
tmpfs                  78M     0   78M   0% /lib/init/rw
udev                   10M   88K   10M   1% /dev
tmpfs                  78M     0   78M   0% /dev/shm
/dev/sda1             137M   17M  114M  13% /boot
/dev/mapper/fileserver-share
40G  177M   38G   1% /var/share
/dev/mapper/fileserver-backup
5.0G  144K  5.0G   1% /var/backup
/dev/mapper/fileserver-media
1.0G   33M  992M   4% /var/media

本文由www.iluther.net翻译(原文在howtoforge),转载请注明出处

lvm新手指南(二)

创建vg,并在vg中加入pv:

vgcreate fileserver /dev/sdb1 /dev/sdc1 /dev/sdd1 /dev/sde1

server1:~# vgcreate fileserver /dev/sdb1 /dev/sdc1 /dev/sdd1 /dev/sde1
Volume group ”fileserver” successfully created

Let’s learn about our volume groups:

vgdisplay

server1:~# vgdisplay
— Volume group —
VG Name               fileserver
System ID
Format                lvm2
Metadata Areas        4
Metadata Sequence No  1
VG Access             read/write
VG Status             resizable
MAX LV                0
Cur LV                0
Open LV               0
Max PV                0
Cur PV                4
Act PV                4
VG Size               93.14 GB
PE Size               4.00 MB
Total PE              23844
Alloc PE / Size       0 / 0
Free  PE / Size       23844 / 93.14 GB
VG UUID               3Y1WVF-BLET-QkKs-Qnrs-SZxI-wrNO-dTqhFP

另一条查看vg的命令:

vgscan

server1:~# vgscan
Reading all physical volumes.  This may take a while…
Found volume group ”fileserver” using metadata type lvm2

vg重命名命令练习:将vg从fileserver改为data

server1:~# vgrename fileserver data
Volume group ”fileserver” successfully renamed to ”data”

再用vgdisplay查看一下配置信息:

server1:~# vgdisplay
— Volume group —
VG Name               data
System ID
Format                lvm2
Metadata Areas        4
Metadata Sequence No  2
VG Access             read/write
VG Status             resizable
MAX LV                0
Cur LV                0
Open LV               0
Max PV                0
Cur PV                4
Act PV                4
VG Size               93.14 GB
PE Size               4.00 MB
Total PE              23844
Alloc PE / Size       0 / 0
Free  PE / Size       23844 / 93.14 GB
VG UUID               3Y1WVF-BLET-QkKs-Qnrs-SZxI-wrNO-dTqhFP

删除vg “data”

server1:~# vgremove data
Volume group ”data” successfully removed

查看一下:

server1:~# vgscan

Reading all physical volumes.  This may take a while…

再重新创建名为fileserver的vg:

vgcreate fileserver /dev/sdb1 /dev/sdc1 /dev/sdd1 /dev/sde1

server1:~# vgcreate fileserver /dev/sdb1 /dev/sdc1 /dev/sdd1 /dev/sde1
Volume group ”fileserver” successfully created

接下来在fileserver这个vg里面创建三个lv,分别是:share (40GB), backup (5GB), and media (1GB) ,共计利用了不到一半的空间,为之后我们做raid1实验埋下伏笔:

 

lvcreate –name share –size 40G fileserver

server1:~# lvcreate –name share  –size 40G fileserver
Logical volume ”share” created

lvcreate –name backup –size 5G fileserver

server1:~# lvcreate –name backup –size  5G fileserver
Logical volume ”backup” created

lvcreate –name media –size 1G fileserver

server1:~# lvcreate –name media  –size  1G fileserver
Logical volume ”media” created

查看一下我们创建的lv:

server1:~# lvdisplay
— Logical volume —
LV Name                /dev/fileserver/share
VG Name                fileserver
LV UUID                280Mup-H9aa-sn0S-AXH3-04cP-V6p9-lfoGgJ
LV Write Access        read/write
LV Status              available
# open                 0
LV Size                40.00 GB
Current LE             10240
Segments               2
Allocation             inherit
Read ahead sectors     0
Block device           253:0

— Logical volume —
LV Name                /dev/fileserver/backup
VG Name                fileserver
LV UUID                zZeuKg-Dazh-aZMC-Aa99-KUSt-J6ET-KRe0cD
LV Write Access        read/write
LV Status              available
# open                 0
LV Size                5.00 GB
Current LE             1280
Segments               1
Allocation             inherit
Read ahead sectors     0
Block device           253:1

— Logical volume —
LV Name                /dev/fileserver/media
VG Name                fileserver
LV UUID                usfvrv-BC92-3pFH-2NW0-2N3e-6ERQ-4Sj7YS
LV Write Access        read/write
LV Status              available
# open                 0
LV Size                1.00 GB
Current LE             256
Segments               1
Allocation             inherit
Read ahead sectors     0
Block device           253:2

lvscan

server1:~# lvscan
ACTIVE            ’/dev/fileserver/share’ [40.00 GB] inherit
ACTIVE            ’/dev/fileserver/backup’ [5.00 GB] inherit
ACTIVE            ’/dev/fileserver/media’ [1.00 GB] inherit

为了练习,我们重命名media这个lv

server1:~# lvrename fileserver media films
Renamed ”media” to ”films” in volume group ”fileserver”

查看效果:

server1:~# lvdisplay
— Logical volume —
LV Name                /dev/fileserver/share
VG Name                fileserver
LV UUID                280Mup-H9aa-sn0S-AXH3-04cP-V6p9-lfoGgJ
LV Write Access        read/write
LV Status              available
# open                 0
LV Size                40.00 GB
Current LE             10240
Segments               2
Allocation             inherit
Read ahead sectors     0
Block device           253:0

— Logical volume —
LV Name                /dev/fileserver/backup
VG Name                fileserver
LV UUID                zZeuKg-Dazh-aZMC-Aa99-KUSt-J6ET-KRe0cD
LV Write Access        read/write
LV Status              available
# open                 0
LV Size                5.00 GB
Current LE             1280
Segments               1
Allocation             inherit
Read ahead sectors     0
Block device           253:1

— Logical volume —
LV Name                /dev/fileserver/films
VG Name                fileserver
LV UUID                usfvrv-BC92-3pFH-2NW0-2N3e-6ERQ-4Sj7YS
LV Write Access        read/write
LV Status              available
# open                 0
LV Size                1.00 GB
Current LE             256
Segments               1
Allocation             inherit
Read ahead sectors     0
Block device           253:2

lvscan

server1:~# lvscan
ACTIVE            ’/dev/fileserver/share’ [40.00 GB] inherit
ACTIVE            ’/dev/fileserver/backup’ [5.00 GB] inherit
ACTIVE            ’/dev/fileserver/films’ [1.00 GB] inherit

删除film这个lv:

server1:~# lvremove /dev/fileserver/films
Do you really want to remove active logical volume ”films”? [y/n]: <– y
Logical volume ”films” successfully removed

再重新创建film这个lv:

lvcreate –name media –size 1G fileserver

server1:~# lvcreate –name media  –size  1G fileserver
Logical volume ”media” created

将media这个lv从1G扩展为1.5G:

server1:~# lvextend -L1.5G /dev/fileserver/media
Extending logical volume media to 1.50 GB
Logical volume media successfully resized

再重新缩回1G:

lvreduce -L1G /dev/fileserver/media

server1:~# lvreduce -L1G /dev/fileserver/media
WARNING: Reducing active logical volume to 1.00 GB
THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce media? [y/n]: <– y
Reducing logical volume media to 1.00 GB
Logical volume media successfully resized

本文由www.iluther.net翻译(原文在howtoforge),转载请注明出处

Next page