ccetc / directory-bundle
Symfony 扩展包,用于构建基于网页的生产商目录。它允许用户通过类别和位置搜索/浏览列表。
Requires
- ccetc/directory-user-bundle: dev-master
- doctrine/common: >=2.2,<3.0
- friendsofsymfony/user-bundle: ~1.3
- isometriks/spam-bundle: dev-master
- knplabs/knp-menu: 2.0.0-alpha1
- knplabs/knp-menu-bundle: 2.0.0-alpha1
- mopa/bootstrap-bundle: ~2.1
- sonata-project/admin-bundle: 2.2.*@dev
- sonata-project/core-bundle: ~2.2@dev
- sonata-project/doctrine-orm-admin-bundle: 2.2.*@dev
- symfony/config: >=2.1,<2.3-dev
- symfony/console: >=2.1,<2.3-dev
- symfony/form: >=2.1,<2.3-dev
- symfony/http-foundation: >=2.1,<2.3-dev
- symfony/routing: >=2.1,<2.3-dev
- symfony/security-bundle: >=2.1,<2.3-dev
- symfony/twig-bridge: >=2.1,<2.3-dev
- symfony/validator: >=2.1,<2.3-dev
- twig/twig: >=1.10,<2.0-dev
This package is not auto-updated.
Last update: 2024-09-14 13:58:25 UTC
README
注意:此包的 master 分支适用于 Symfony 2.2。2.1 分支经过 Symfony 2.1 测试。
CCETC/DirectoryBundle 是一个用于构建基于网页的“列表”目录的包。
开发跟踪在 trello 板上。
特性
DirectoryBundle 包含设置具有以下功能的 Symfony 应用所需的一切
- 用户可以通过分页列表或谷歌地图浏览列表
- 用户可以添加自己的列表,等待管理员批准
- 管理员可以创建/编辑/删除/批准列表
它无需配置即可立即运行,但大多数用例将需要大量的开发者定制。包中的几乎所有内容都很容易由开发者扩展。常见的定制包括
- 添加字段
- 可用于搜索的自定义字段
- 添加“属性”(例如:肉类生产商目录中的“属性”如“有机”和“草饲”……属性是具有与列表关系的一个实体)
- 自定义模板
- 自定义和添加页面
- 自定义设计
安装
选项 1 - 从头开始安装
安装一个 Symfony 应用
使用 Symfony 安装指南 安装您的 Symfony 应用
请确保设置您的数据库。
安装 DirectoryBundle
将其添加到您的 composer.json
"require": {
"ccetc/directory-bundle": "dev-master"
}
运行 php composer.phar install
这将安装该包及其所有依赖项。
关于 Bootstrap 和 jQuery 的说明
jQuery 和 Twitter Bootstrap 包含在此包中。您可以在包中包含自己的副本,并扩展基本布局以包含自己的文件而不是默认文件。
遵循 SonataAdmin 的安装指南
http://sonata-project.org/bundles/admin/master/doc/reference/installation.html
将 DirectoryBundle 和依赖项添加到 AppKernel.php->registerBundles
new Knp\Bundle\MenuBundle\KnpMenuBundle(),
new Sonata\BlockBundle\SonataBlockBundle(),
new Sonata\jQueryBundle\SonatajQueryBundle(),
new Sonata\AdminBundle\SonataAdminBundle(),
new Sonata\DoctrineORMAdminBundle\SonataDoctrineORMAdminBundle(),
new CCETC\DirectoryBundle\CCETCDirectoryBundle(),
new MyDirectory\AppBundle\MyDirectoryAppBundle(),
new Mopa\Bundle\BootstrapBundle\MopaBootstrapBundle(),
注意:务必在应用程序包之前添加该包,以便您可以覆盖翻译。
将您的包设置为 DirectoryBundle 的“子包”
要覆盖模板,请使您的应用程序包成为 DirectoryBundle 的子包。在您的包的 Bundle 类中(例如:在包根目录中的 MyBundle.php)
public function getParent()
{
return 'CCETCDirectoryBundle';
}
配置
将以下内容添加到您的 config.yml
,并用您的应用程序信息填写值
ccetc_directory:
bundle_name: MyBundle
bundle_path: \My\Bundle
title: My Directory
logo: bundles/mybundle/images/mylogo.png
menu_builder: MyBundle:Builder:mainMenu
layout_template: MyBundle::layout.html.twig
copyright: Our Company 2013
contact_email: contact@email.com
admin_email: admin@email.com
og_description: your description
site_url: http://yoururl
google_maps_key: yourkey
google_analytics_account: UA-NNNNNNNNN-1
always_show_advanced_search: false
sonata_block:
default_contexts: [cms]
blocks:
sonata.admin.block.admin_list:
contexts: [admin]
ccetc.directory.block.admin_listing_approval:
contexts: [admin]
sonata_admin:
templates:
layout: CCETCDirectoryBundle::admin_layout.html.twig
show: CCETCDirectoryBundle:Admin:show.html.twig
edit: CCETCDirectoryBundle:Admin:edit.html.twig
dashboard:
blocks:
# display a dashboard block
- { position: left, type: ccetc.directory.block.admin_listing_approval }
- { position: left, type: sonata.admin.block.admin_list }
注意:位置管理类不应包含在后台界面中。如果使用基本 HTTP 身份验证,最简单的方法是在您的配置文件中手动定义哪些类应该出现
groups:
listings:
label: Listings
items: [ccetc.directory.admin.listing]
data:
label: Data
items: [ccetc.directory.admin.attribute, ccetc.directory.admin.product]
如果您使用 CMS 功能,还应包含“页面”管理类
groups:
...
content:
label: Content
items: [ccetc.directory.admin.page]
DirectoryBundle 配置选项
- bundle_name - 包名称 - 必需
- bundle_path - 包路径 - 必需
- title - 用于页面标题、标题、og 标签 - 必需
- logo - 用于页眉 - 可选
- menu_builder - 要使用的菜单 - 可选
- layout_template - 用于所有页面的基本模板
- copyright - 用于页脚 - 可选
- contact_email - 用于页脚 - 必需
- admin_email - 用于电子邮件通知 - 必需
- og_* - 用于 og 元标签
- google_maps_key - 可选
- google_analytics_account - 可选
- always_show_advanced_search - 可选,默认为 false
- registration_setting - 可选 - 默认为 none (required|optional|none)
- use_expiration - 可选 - 默认为 true
- listing_lifetime - 列表到期前的天数 - 可选 - 默认 365
- renew_listing_on_update - 是否在编辑时续订列表 - 可选 - 默认 true
创建您的实体
您需要创建自己的实体并扩展提供的基实体和示例 dist
文件。至少您需要一个扩展 Base Listing
的 Listing
实体。
位置实体
如果您想允许用户通过他们所在位置和列表位置之间的距离进行搜索,您需要扩展提供的 dist 文件中的 ListingLocation
、LocationDistance
、UserLocation
和 UserLocationAlias
实体。
属性实体
大多数安装至少将有一个与他们的 Listing
相关的 Attribute
。这可以用来添加产品(例如:鸡、鸭、牛肉、猪肉)和/或实际属性(例如:有机、草饲、无激素)。要使用此功能,请扩展 BaseAttribute
或使用 Attribute.php.dist
文件。
创建您的管理类
您需要添加将它们与您的实体相关联的服务。对于您创建的每个实体,您需要以下之一,其中实体的路径(参数 #2)已定制
<service id="ccetc.directory.admin.listing" class="CCETC\DirectoryBundle\Admin\ListingAdmin">
<tag name="sonata.admin" manager_type="orm" group="Listings" label="Listings"/>
<argument />
<argument>Acme\DemoBundle\Entity\Listing</argument>
<argument>CCETCDirectoryBundle:ListingAdmin</argument>
</service>
<service id="ccetc.directory.admin.attribute" class="CCETC\DirectoryBundle\Admin\AttributeAdmin">
<tag name="sonata.admin" manager_type="orm" group="Data" label="Attributes"/>
<argument />
<argument>Acme\DemoBundle\Entity\Attribute</argument>
<argument>SonataAdminBundle:CRUD</argument>
</service>
<service id="ccetc.directory.admin.listinglocation" class="CCETC\DirectoryBundle\Admin\ListingLocationAdmin">
<tag name="sonata.admin" manager_type="orm" group="Location Data" label="Listing Locations"/>
<argument />
<argument>Acme\AppBundle\Entity\ListingLocation</argument>
<argument>SonataAdminBundle:CRUD</argument>
</service>
<service id="ccetc.directory.admin.userlocation" class="CCETC\DirectoryBundle\Admin\UserLocationAdmin">
<tag name="sonata.admin" manager_type="orm" group="Location Data" label="User Locations"/>
<argument />
<argument>Acme\DemoBundle\Entity\UserLocation</argument>
<argument>SonataAdminBundle:CRUD</argument>
</service>
<service id="ccetc.directory.admin.userlocationalias" class="CCETC\DirectoryBundle\Admin\UserLocationAliasAdmin">
<tag name="sonata.admin" manager_type="orm" group="Location Data" label="User Location Aliases"/>
<argument />
<argument>Acme\DemoBundle\Entity\UserLocationAlias</argument>
<argument>SonataAdminBundle:CRUD</argument>
</service>
<service id="ccetc.directory.admin.locationdistance" class="CCETC\DirectoryBundle\Admin\LocationDistanceAdmin">
<tag name="sonata.admin" manager_type="orm" group="Location Data" label="Location Distances"/>
<argument />
<argument>Acme\DemoBundle\Entity\LocationDistance</argument>
<argument>SonataAdminBundle:CRUD</argument>
</service>
注意:ListingAdmin
应使用捆绑中的自定义控制器(CCETCDirectoryBundle:ListingAdmin
)。
路由
将以下内容添加到您的应用程序的 routing.yml
ccetc_directory:
resource: "@CCETCDirectoryBundle/Resources/config/routing.yml"
prefix: /
保护您的应用程序
您想要保护应用程序的行政部分。在 security.yml
中可以像这样操作
security:
firewalls:
secured_area:
pattern: ^/
anonymous: ~
http_basic:
realm: "Secured Admin Area"
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
providers:
in_memory:
memory:
users:
admin: { password: admin, roles: 'ROLE_ADMIN, ROLE_SONATA_ADMIN' }
encoders:
Symfony\Component\Security\Core\User\User: plaintext
为电子邮件和列表到期创建 cron 任务
您应该创建一个 cron 来运行您配置的电子邮件队列。
另外,如果使用列表到期,您还需要每天运行以下命令的 cron 任务
php app/console ccetc:directory:update-expired-listings
php app/console ccetc:directory:send-pending-expiration-notifications
启用垃圾邮件预防
添加到 AppKernel.php
new Isometriks\Bundle\SpamBundle\IsometriksSpamBundle(),
添加到 config.yml
isometriks_spam:
timed:
min: 7
max: 10000
global: false
message: You're submitting the form too quickly.
honeypot:
field: email_address
use_class: false
hide_class: hidden
global: false
message: Please contact us
确保将这些选项添加到您的注册表单中
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
...
'timed_spam' => true,
'honeypot' => true,
));
}
选项 2 - 安装 DirectoryAppTemplate
遵循 DirectoryAppTemplate 上的说明。
定制
由于您的应用程序是 DirectoryBundle 的子捆绑,因此您可以定制大多数内容,以下链接可以帮助确定如何进行不同的定制
- https://symfony.com.cn/doc/current/cookbook/bundles/inheritance.html
- https://symfony.com.cn/doc/current/cookbook/bundles/override.html
用户登录和列表编辑
有一些可选功能可以从“注册”页面创建用户账户,允许用户编辑列表,并允许管理员管理用户。
设置
-
FOSUserBundle 和 CCETCDirectoryUserBundle 已经安装
-
遵循 FOSUserBundle 安装说明(在您的应用程序捆绑中创建用户实体,更改 routing.yml、config.yml、security.yml)
**Note**: Your User class should extend ``CCETCDirectoryUserBundle\Entity\BaseUser``
-
将 CCETCDirectoryUserBundle 添加到 AppKernel 的末尾。这里的顺序对于翻译定制很重要
new My\AppBundle\MyAppBundle(), new FOS\UserBundle\FOSUserBundle(), new CCETC\DirectoryBundle\CCETCDirectoryBundle(), new CCETC\DirectoryUserBundle\CCETCDirectoryUserBundle(),
-
编辑 config.yml
ccetc_directory: registration_setting: required If using optional registration: fos_user: registration: form: type: ccetc_directory_user_registration confirmation: enabled: true
-
将 ROLE_SONATA_ADMIN 添加到 ROLE_ADMIN 角色 security.yml 中
security: role_hierarchy: ROLE_ADMIN: [ROLE_USER, ROLE_SONATA_ADMIN] ROLE_SUPER_ADMIN: ROLE_ADMIN
-
添加用户/列表关系
In Listing.php: /** * @ORM\OneToOne(targetEntity="User", inversedBy="listing") * @ORM\JoinColumn(name="user_id", referencedColumnName="id") **/ private $user; In User.php: /** * @ORM\OneToOne(targetEntity="BaseListing", mappedBy="user", cascade={"persist", "remove"}) **/ private $listing;
-
添加管理服务
<service id="ccetc.directoryuser.admin.user" class="CCETC\DirectoryUserBundle\Admin\UserAdmin"> <tag name="sonata.admin" manager_type="orm" group="Users" label="Users"/> <argument /> <argument>My\AppBundle\Entity\User</argument> <argument>CCETCDirectoryUserBundle:UserAdmin</argument> <call method="setUserManager"> <argument type="service" id="fos_user.user_manager" /> </call> </service>
-
将管理类添加到 config.yml 中
sonata_admin: ... dashboard: ... groups: ... users: label: Users items: [ccetc.directoryuser.admin.user]
-
更新数据库并清除缓存!
定制
- 有一个可定制的编辑表单类型和处理程序,其方式与注册表单相同
- 还有可定制的编辑模板,其方式与注册模板相同
模板
只需将任何 DirectoryBundle 模板包含到您的捆绑中即可覆盖默认模板。
布局
如果您想扩展基本布局,您需要给它一个唯一名称(app_layout.html.twig
)并在配置中设置此模板路径。
配置和路由
如果您不想覆盖提供的服务和路由,您应该将您的路由和配置命名为除 routing.yml
和 services.xml
之外的内容。另一种选择是将这些文件的内容复制到您自己的。
菜单
您可以定义自己的菜单类,并使用上面文档化的配置选项覆盖所使用的类。
翻译
您可以通过将 Resources/translations
复制到您的包中来覆盖翻译。确保在目录包或您的自定义之后将您的应用程序包添加到 AppKernel 中,否则您的自定义将不会被使用。
实体
您可以为创建的实体添加自定义字段或字段覆盖。请确保将您的自定义字段添加到以下位置
- 实体类
- 管理类
- 注册表单
- 前端模板
一些有用的资源
管理类
您可以使用提供的管理类进行扩展
use CCETC\DirectoryBundle\Admin\ListingAdmin as BaseListingAdmin;
class ListingAdmin extends BaseListingAdmin
{
protected function configureFormFields(FormMapper $formMapper)
{
parent::configureFormFields($formMapper);
$formMapper
->with('Products')
->add('myField')
->end()
;
}
}
注意:请确保未使用前端中的任何实体或字段不会出现在您的注册表单或管理类中
验证
将 validation.yml.dist
复制到您的包中,并根据需要自定义。
前端过滤器
目录使用 ListingAdmin.datagrid
对前端进行过滤。选项 isAdvanced
等于 true
的过滤器将被放入“高级搜索”部分。选项 'hideValue' 设置为 true 的过滤器将隐藏其值表单输入。
注册表单
注册表单、表单类型和处理程序作为服务存在,因此您可以为提供自己的表单、表单类型和/或处理程序并覆盖服务。请确保同时覆盖表单模板。
<service id="ccetc.directory.form.handler.signup" class="My\AppBundle\Form\Handler\SignupFormHandler" scope="request">
<argument type="service" id="ccetc.directory.form.signup" />
<argument type="service" id="request" />
<argument type="service" id="service_container" />
</service>
我们已经在表单类型中实现了一种非常简单的方法来自动化表单集/字段组。任何自定义表单类型都必须有一个返回格式为 "Fieldset Label" => array("field1", "field2")
的 getFieldsets
方法。
自定义页面
您可以使用默认控制器为您页面使用以下代码在您的路由中
defaults: { _controller: CCETCDirectoryBundle:Pages:static, template: MyBundle:Pages:myPage.html.twig }
默认检查了过时的浏览器,包括一个布尔值,当渲染您的模板时会显示结果。
SEO
已经实施了一些功能,使管理员/开发者能够实现 SEO
- 管理员可以从 CMS 编辑“页面”标题、描述、url、h1 标题
- 非 CMS 页面的标题和描述必须由开发者自定义。只需使用
title
和meta_description
twig 块即可。 - 列表页面的 url、标题、h1 和 meta 描述可以使用
listing_type
下的配置选项进行自定义- listings_h1_heading
- listings_route_pattern
- listings_meta_description
- listings_meta_title
我还设法通过在一个应用程序中的一些技巧提供了基于属性过滤的不同标题/urls/descriptions。查看 ReUseDirectory 代码或向我询问。
多种列表类型
在初始开发之后,我们添加了定义多个列表类型的选项。此配置是可选的,并且该包应该在无需任何新配置更改的情况下正常工作,但这尚未完全测试。
以下是一些设置使用两个列表类型的应用程序的说明。配置相当简单,大多数情况下安装和自定义与单个列表类型相同。
配置
cce_directory:
listing_type_config:
- { admin_service: 'ccetc.directory.admin.listinga', entity_class_path: '\My\AppBundle\Entity\ListingA', translation_key: 'listinga' }
- { admin_service: 'ccetc.directory.admin.listingb', entity_class_path: '\My\AppBundle\Entity\ListingB', translation_key: 'listingb', use_maps: false, use_profiles: false }
选项
- admin_service - 此类型实体管理类的服务
- entity_class_path - 此类型实体的路径
- translation_key - 翻译键将在模板中使用,需要大写和复数化,因此您提供的任何翻译都应使用此键。 此键还用于唯一标识列表类型 - 因此它必须是唯一的。
- use_profile - 布尔值,可选,默认:true(如果为 false,则配置文件路由将重定向到包含单个列表的列表页面)
- use_maps - 布尔值,可选,默认:true(如果为 false,则地图选项卡将不会出现在列表页面
位置
目前,只支持一个列表类别使用位置功能。虽然可以实现,但对我们项目来说不是必需的,而且操作过于复杂。在构建类、服务、类名和关系字段名时,仍应使用“列表”一词(例如:ListingLocation是类名,listings是关系字段等)。
假设
为了保持配置选项少,我们做出了一些假设
- 如果需要在不同类型之间自定义列表块、个人资料和注册模板,它们的名称应遵循以下格式:type->translationKey + "_profile"。如果您想自定义模板,但所有类型都共享它,则可以使用常规名称。
- 三个注册服务是必需的,格式为 "ccetc.direction.x.x." + type->translationKey + "signup"
工具
有一些twig变量和函数可用
- listingListingType - 可用的第一个列表类型(如果您只有一个并且需要获取路由等,可以使用)
- getListingTypeForObject(listing) - 返回对象列表类型(该对象是列表)
- getListingTypeByKey(stringKey) - 返回与翻译键匹配的列表类型
其他注意事项
- 所有列表类型都应该扩展具有用户关系字段的自定义BaseListing类(在用户端应仍然称为"列表")
其他功能
管理员显示/编辑钩子
如果您需要在管理员表单或显示页面之前或之后包含自定义模板,请按以下方式定义模板路径
public $showPreHook = array(
'template' => 'MyBundle:Admin:_my_template.html.twig'
);
可用的Twig全局变量
以下全局变量可以通过任何模板访问
directoryTitle
directoryLogo
directoryMenuBuilder
layoutTemplate - all page templates should extend this
directoryContactEmail
directoryCopyright
directoryOgDescription
directorySiteURL
googleMapsKey
googleAnalyticsAccount
查找列表块
您可以在页面中包含查找列表块。只需确保将其包裹在具有类find-a-listing
的div中即可。
<div class="find-a-listing alert alert-block alert-info">
{{ render(controller('CCETCDirectoryBundle:Directory:findAListing', {'attributeClass': 'Category', 'attributeFieldName' : 'categories' } )) }}
</div>
属性参数是可选的。如果包含,则会在块中显示该属性的下拉列表。