OctoberCMS 静态页面内的静态页面下拉列表

Static page dropdown within static page in OctoberCMS

我有一个包含幻灯片的模板。每张幻灯片包括:

对于前 3 个项目,我在我的模板中设置了以下内容:

{repeater name="slideshow" prompt="Add another slide" tab="Slideshow"}
  {variable name="image" label="Image" type="mediafinder" mode="image"}{/variable}
  {variable name="caption" type="text" label="Caption"}Caption{/variable}
  {variable name="body" type="textarea" label="Body"}Body{/variable}
{/repeater}

但是,我对按钮使用什么字段类型有点困惑,它需要 link 到站点内的静态页面。

我不想使用用户可以输入 URL 的文本框,因为用户很难理解。我宁愿有一个下拉菜单,其工作方式与静态菜单插件相同(即:select "Static Page" 来自 "type",然后在第二个下拉菜单中获取静态页面列表菜单),但不清楚如何执行此操作。

是的,您可以在其中添加带有静态页面列表的下拉菜单。

要在下拉列表中显示页面列表,您需要扩展页面并向其添加动态方法,以便在转发器添加下拉列表时它将从该方法中获取 values/options。

您需要在任何插件中向 启动方法 添加代码,它将扩展页面 class,从而进一步处理 ajax 请求。

    \RainLab\Pages\Classes\Page::extend(function($model) {
        $model->addDynamicMethod('getPageOptions', function() {
            $theme = \Cms\Classes\Theme::getEditTheme();
            $pageList = new \RainLab\Pages\Classes\PageList($theme);
            $pages = [];
            foreach ($pageList->listPages() as $name => $pageObject) {
                $pages[$pageObject->url] = $pageObject->title . ' (' . $pageObject->url . ')';
            }
            return $pages;
        });
    });

在你的转发器中你可以添加下拉菜单

    {repeater name="slideshow" prompt="Add another slide" tab="Slideshow"}
      {variable name="image" label="Image" type="mediafinder" mode="image"}{/variable}
      {variable name="caption" type="text" label="Caption"}Caption{/variable}
      {variable name="body" type="textarea" label="Body"}Body{/variable}
      {variable name="page" type="dropdown" label="Page"}{/variable}
    {/repeater}

所以你可以看到我们添加了动态方法 getPageOptions 它由三部分组成 1: get 2nd: fieldname 第三:选项

So our method name will be get + Page + Options => getPageOptions

在该页面中,我们return将数组作为值 => 标签对,您可以根据需要在此处自定义。

因此,当创建下拉菜单时,它将搜索此方法并使用其 return 值作为选项。

如果您发现任何其他困难,请发表评论。

更新

好的,现在我们终于可以添加条件下拉菜单了 到目前为止,它 ajax 不可更新,但是我们可以根据条件隐藏和显示它。

您可以在布局中添加此标记。

    {repeater name="slideshow" prompt="Add another slide" tab="Slideshow"}
      {variable name="type" type="dropdown" label="Link Type"}{/variable}
      {variable name="cms-page" type="dropdown" label="Cms Page" trigger="action:show|field:type|condition:value[cms-page]" }{/variable}
      {variable name="static-page" type="dropdown" label="Static Page" trigger="action:show|field:type|condition:value[static-page]"}{/variable}
      {variable name="blog-post" type="dropdown" label="Post" trigger="action:show|field:type|condition:value[blog-post]"}{/variable}
    {/repeater}

然后在插件中你需要添加一些额外的方法。

your boot method of plugin.php look like this

public function boot()
{

    $pluginSelf = $this;
    \RainLab\Pages\Classes\Page::extend(function($model) {
            $model->addDynamicMethod('getTypeOptions', function() {

            return [
                '' => 'Select Type',
                'cms-page' => 'CMS page',
                'static-page' => 'Static Page',
                'blog-post' => 'Blog post'
            ];

        });
    });

    \RainLab\Pages\Classes\Page::extend(function($model) use ($pluginSelf) {
        $model->addDynamicMethod('getStaticPageOptions', function() use ($pluginSelf) {
            $result =  $pluginSelf::getTypeInfo('static-page');
            return $result['references'];
        });
    });

    \RainLab\Pages\Classes\Page::extend(function($model) use ($pluginSelf) {
        $model->addDynamicMethod('getCmsPageOptions', function() use ($pluginSelf) {
            $result =  $pluginSelf::getTypeInfo('cms-page');
            return $result['references'];
        });
    });

    \RainLab\Pages\Classes\Page::extend(function($model) use ($pluginSelf) {
        $model->addDynamicMethod('getBlogPostOptions', function() use ($pluginSelf) {
            $result = $pluginSelf::getTypeInfo('blog-post'); 
            return $result['references'];
        });
    });

}

and one additional method you need to add inside plugin.php

public static function getTypeInfo($type)
{
    $result = [];
    $apiResult = \Event::fire('pages.menuitem.getTypeInfo', [$type]);

    if (is_array($apiResult)) {
        foreach ($apiResult as $typeInfo) {
            if (!is_array($typeInfo)) {
                continue;
            }

            foreach ($typeInfo as $name => $value) {
                if ($name == 'cmsPages') {
                    $cmsPages = [];

                    foreach ($value as $page) {
                        $baseName = $page->getBaseFileName();
                        $pos = strrpos($baseName, '/');

                        $dir = $pos !== false ? substr($baseName, 0, $pos).' / ' : null;
                        $cmsPages[$baseName] = strlen($page->title)
                            ? $dir.$page->title
                            : $baseName;
                    }

                    $value = $cmsPages;
                }

                $result[$name] = $value;
            }
        }
    }

    return $result;
}

因此,您可以在第一个下拉菜单中看到我们可以选择 'cms-page'、'static-page' 和 'Blog post',基于此我们可以显示其他下拉菜单。

并且在显示或使用结果期间,首先您需要根据该字段值检查 type 字段的值,您可以进一步选择您需要使用的下拉列表值,例如 type=cms-page 然后你需要寻找 cms-page 字段。

notice : not sure used - (dash) in variables so if value is not in out put you can convert variables in cmsPage camel case if needed not sure about this stuff

一个额外的变化你需要添加这个变化作为它改变核心文件的要求,我也为它创建了拉取请求所以他们也包括在下一个版本中的变化意味着我们需要手动完成。 它需要才能工作
请参考此 PR 请求:https://github.com/octobercms/library/pull/292/files

如果您不需要 link CMS 页面,您可以使用 staticpagepicker 小部件。 https://github.com/rainlab/pages-plugin#backend-forms

If you need to select from a list of static pages in your own backend forms, you can use the staticpagepicker widget:

fields:
    field_name:
        label: Static Page
        type: staticpagepicker

The field's assigned value will be the static page's file name, which can be used to link to the page as described above.

在您的布局文件中:

{variable name="button_page" label="Button URL" type="staticpagepicker"}{/variable}

<a href="{{ button_page | staticPage }}">Button</a>

由于 CMS 页面未在此小部件中列出,您始终可以设置一个替代字段以为用户提供更大的灵活性。

{variable name="button_url" label="Button (URL)" type="text" span="left" comment="Leave empty if using Button (Page) instead" placeholder="http://"}{/variable}
{variable name="button_page" label="Button (Page)" type="staticpagepicker" span="right" comment="Used if Button (URL) is left empty"}{/variable}

<a href="{{ button_url ? button_url : (button_page | staticPage) }}">Button</a>

我和 Panagiotis Koursaris 有同样的问题。我使用了没有中继器的模板变量。我通过指定选项并在插件引导方法中添加别名来解决问题。 例如:

{variable name="type" type="dropdown" options="StaticPage | getTypeOptions" label="Link Type" tab="Text Image Header (dark)"}{/variable}

\Illuminate\Foundation\AliasLoader::getInstance()->alias('StaticPage','RainLab\Pages\Classes\Page');

但是触发器不起作用,显示了所有下拉菜单。 有解决办法吗?

下一个问题是,所有cms页面显示如下:

projects [projects]

我在第二个循环中修改代码如下:

if ($type == 'cms-page') {
            $cmsPages = [];

            if (!is_array($value)) {
              continue;
            }

            foreach ($value as $url => $pageArray) {
              $page = \Cms\Classes\Page::find($url);
              if ($page) {
                $baseName = $page->getBaseFileName();
                $pos = strrpos($baseName, '/');

                $dir = $pos !== false ? substr($baseName, 0, $pos) . ' / ' : null;
                $cmsPages[$baseName] = strlen($page->title) ? $dir . $page->title : $baseName;
              }
            }

            $value = $cmsPages;
          }