代码之家  ›  专栏  ›  技术社区  ›  Joseph

10月CMS中静态页面内的静态页面下拉列表

  •  1
  • Joseph  · 技术社区  · 7 年前

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

    • 形象
    • 说明文字
    • 一段文字
    • 按钮

    对于前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}
    

    然而,我对按钮使用的字段类型有点困惑,它需要链接到站点内的静态页面。

    我不想使用用户可以输入URL的文本框,因为这对用户来说太难理解了。我希望有一个与静态菜单插件工作方式相同的下拉菜单(即:从“类型”中选择“静态页面”,然后在第二个下拉菜单中获得静态页面列表),但它看不到明显的方法。

    3 回复  |  直到 7 年前
        1
  •  3
  •   Hardik Satasiya    7 年前

    是的,您可以在那里添加带有静态页面列表的下拉列表。

    要在下拉列表中显示页面列表,您需要扩展页面并向其添加动态方法,这样当repeater add下拉列表时,它将从该方法中获取其值/选项。

    您需要将代码添加到 引导方法 在任何插件中,它都将扩展pages类,该类可以进一步处理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部分: 收到 第二名: 字段名 第三:选项

    因此,我们的方法名称为 获取+页面+选项 => getPageOptions

    在该页面中,我们将返回数组作为值=>您可以根据需要定制标签对。

    因此,当创建下拉列表时,它将搜索此方法并使用其返回值作为选项。

    如果您发现任何进一步的困难,请评论。

    使现代化

    现在我们终于可以添加条件下拉列表了 到目前为止,它还不可更新,但我们可以根据条件隐藏和显示它。

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

        {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}
    

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

    你的 插件的引导方法。php 像这样

    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'];
            });
        });
    
    }
    

    另一种方法 你需要添加内部 插件。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页面”、“静态页面”和“博客帖子”,基于此,我们可以显示其他下拉列表。

    在显示或使用结果的过程中,首先需要检查 类型 字段基于该字段值,您可以进一步选择需要使用的下拉列表值,例如 类型=cms页面 那么你需要寻找 cms页面 领域

    注意:不确定是否在变量中使用了-(破折号),所以如果值不是in-out-put,则可以在中转换变量 cmsPage公司 骆驼箱,如果需要的话,不确定这东西

    作为更改核心文件所需的额外更改,您需要添加此更改,我还为其创建了pull请求,以便在下一版本中也包括此更改,这意味着我们需要手动执行此更改。 its要求 为了让它起作用
    请参阅本请购单: https://github.com/octobercms/library/pull/292/files

        2
  •  0
  •   Jeremy M    6 年前

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

    如果需要从自己后端表单中的静态页面列表中进行选择,可以使用 静态页面选择器 小装置:

    fields:
        field_name:
            label: Static Page
            type: staticpagepicker
    

    该字段的赋值将是静态页面的文件名,可用于如上所述链接到页面。

    在布局文件中:

    {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>
    
        3
  •  0
  •   Hacko    4 年前

    我也有同样的问题,就像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页面显示如下:

    项目[项目]

    我将第二个循环中的代码更改如下:

    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;
              }