我正在尝试创建自己的xml站点地图。一切都已完成,除了我认为最容易的部分。如何获得网站上所有页面的列表?我在/ site文件夹和其他一些文件夹中有很多视图。有没有办法明确请求他们的URL或可能通过控制器?
我不想使用扩展程序
答案 0 :(得分:9)
您可以使用反射来遍历所有控制器的所有方法:
Yii::import('application.controllers.*');
$urls = array();
$directory = Yii::getPathOfAlias('application.controllers');
$iterator = new DirectoryIterator($directory);
foreach ($iterator as $fileinfo)
{
if ($fileinfo->isFile() and $fileinfo->getExtension() == 'php')
{
$className = substr($fileinfo->getFilename(), 0, -4); //strip extension
$class = new ReflectionClass($className);
foreach ($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method)
{
$methodName = $method->getName();
//only take methods that begin with 'action', but skip actions() method
if (strpos($methodName, 'action') === 0 and $methodName != 'actions')
{
$controller = lcfirst(substr($className, 0, strrpos($className, 'Controller')));
$action = lcfirst(substr($methodName, 6));
$urls[] = Yii::app()->createAbsoluteUrl("$controller/$action");
}
}
}
}
答案 1 :(得分:1)
您需要知道要在sitemap.xml中包含哪些内容,我真的不认为您希望在sitemap.xml中包含所有页面,或者您是否真的想要包含诸如site.com/之类的内容article / edit / 1?
也就是说,您可能只想要控制器中view
操作的结果。事实是,你需要知道你想要索引什么。
不要考虑控制器/操作/视图,而是考虑系统中要索引的资源,无论是文章还是页面,它们都在您的数据库中或以某种方式存储,因此您可以列出它们,并且它们有一个标识它们的URI,获取URI是一个调用几个函数的问题。
答案 2 :(得分:1)
有两种可能性 -
您正在运行静态网站,然后您可以在1个文件夹中找到所有HTML - protected / views / site / pages http://www.yiiframework.com/wiki/22/how-to-display-static-pages-in-yii/
网站是动态的。生成和重新生成站点地图等任务可以归类为后台任务。
可以通过使用 - WGET , GET 或 lynx 命令
或者,您可以将CronController创建为 CConsoleCommand 。如何使用YII中的命令显示在下面的链接中 - http://tariffstreet.com/yii/2012/04/implementing-cron-jobs-with-yii-and-cconsolecommand/
Sitemap是一个列出您网站网址的XML。但它不止于此。 它可以帮助您可视化网站的结构,您可能有
在制作有用的 扩展程序 时,可以在设计之前考虑以上几点。
像 Wordpress 这样的框架提供了生成分类站点地图的方法。 因此,每个页面的元数据都是从之前存储并使用它发现的元数据和组页面。
@Pavle 建议的反思解决方案很好,应该是可行的方法。 考虑可能有部分视图,您可能希望也可能不希望将它们列为单独的链接。
因此,您希望为创建扩展所付出的努力也取决于其中一些。
您可以要求用户列出配置文件中的所有变量,然后从那里开始或,您必须使用 reflection 和解析页面并寻找正则表达式。
对于ex - 基于模块名称,您可以先将它们分组,模块内的控制器可以形成子组。
答案 3 :(得分:1)
第一种方法可能是迭代视图文件,但是您必须考虑到在某些情况下,视图不是页面目标,而是使用CController::renderPartial()
方法包含在其他页面中的页面部分。通过探索CController的类引用,我发现了CController::actions()
方法。
所以,我没有找到任何 Yii方式来迭代CController的所有动作,但我使用php在我的一个项目中迭代SiteController的所有方法并过滤它们这些是前缀'action',这是我的动作前缀,这是示例
class SiteController extends Controller{
public function actionTest(){
echo '<h1>Test Page!</h1></p>';
$methods = get_class_methods(get_class($this));
// The action prefix is strlen('action') = 6
$actionPrefix = 'action';
$reversedActionPrefix = strrev($actionPrefix);
$actionPrefixLength = strlen($actionPrefix);
foreach ($methods as $index=>$methodName){
//Always unset actions(), since it is not a controller action itself and it has the prefix 'action'
if ($methodName==='actions') {
unset($methods[$index]);
continue;
}
$reversedMethod = strrev($methodName);
/* if the last 6 characters of the reversed substring === 'noitca',
* it means that $method Name corresponds to a Controller Action,
* otherwise it is an inherited method and must be unset.
*/
if (substr($reversedMethod, -$actionPrefixLength)!==$reversedActionPrefix){
unset($methods[$index]);
} else $methods[$index] = strrev(str_replace($reversedActionPrefix, '', $reversedMethod,$replace=1));
}
echo 'Actions '.CHtml::listBox('methods', NULL, $methods);
}
...
}
我得到的输出是......
我确信它可以进一步完善,但这种方法适用于你拥有的任何控制器......
所以你需要做的是:
对于每个Controller:使用上述方法过滤掉类的所有非动作方法。您可以构建一个像
这样的关联数组array(
'controllerName1'=>array(
'action1_1',
'action1_2'),
'controllerName2'=>array(
'action2_1',
'action2_2'),
);
我会在我的SiteController中为此添加一个静态方法getAllActions()。
get_class_methods,get_class,strrev和strlen都是PHP函数。
答案 4 :(得分:1)
根据您的问题: 1.如何获得网站上所有页面的列表?
基于Yii的模块/控制器/动作/ action_params方式以及构建SEO站点地图的需要。
下一个最佳解决方案是拥有一个内容数据库,您知道如何通过url规则获取每个内容,然后通过cron控制台作业创建所有要保存为sitemap.xml的URL。
希望这有帮助!