问题描述
我已经从客户端获得了一项新任务,该任务基本上是为演员/歌手等创建CMS等.
它基本上将是一个软件包,并且将与WordPress几乎相似,您只需移交给购买它的人,但这当然不会是一个博客平台.它将允许开发人员:
- 添加插件/小部件
- 添加模板/主题
我以为观察者模式可能有用,但我不太确定.你们可以建议以以下方式创建如此灵活/可扩展的CMS:
- 能够添加插件的能力(例如WordPress)
- 能够添加主题/模板的能力(例如WordPress)
- 设计模式
- 其他任何事情
推荐答案
观察者的良好,但是您必须考虑超越基本模式.规范观察者/主题模式只会将主题对象发送给观察者,别无他物,甚至没有通知 为什么会被通知.
最初,该解决方案似乎还包括向观察者通知的原因,但是您最终可能会通知观察者不关心某些通知.更好的解决方案可能是要求观察者还要求收到的通知列表.
但这也带来了问题.为了使观察者实际上将自己固定在受试者身上,必须实例化.每一次.即使不需要它们.那是愚蠢的.
因此,我们很快就达到了插件的规范PHP实现之一:"钩子".钩子使用与观察者/受试者相同的概念,但是实现方式是一种非常重要的方式:实际观察者并没有实例化以观察受试者.相反,受试者向某些中央存储库发送通知.该存储库配置为已安装和激活的插件(观察者)的列表,并包含每个插件想要接收的所有事件的列表.每个插件并仅在事件发生时才通知,通常是通过静态方法而不是通过创建插件实例并通知该插件. call_user_func_array和一个好的自动加载器使它变得非常琐碎.
因此,您可以创建一个简单的接口供所有插件实现.您需要包括但不限于:
的方法- 可以获取有关插件的数据,例如名称,作者,官方网站,版本等.人为消耗的信息.
- 一种返回插件的事件的方法.
- 一种安装方法,对于插件需要做的事情,例如操纵数据库.
- 一种卸载方法也可能方便.
- (可能是静态的)方法将接收事件通知并返回所需的任何数据.
根据您采用插件概念的距离,您最终可能会获得具有可配置选项的插件.您可能需要考虑到这一点.沿着那条道路是疯狂和配置系统.
为了使插件有效,您将需要将挂钩到处,并且经常与最终用户一起添加需要的新钩子.
小部件可以轻松地以类似的方式工作,就像在页面渲染之前被调用的插件.
主题/模板,哦,我的.您可能有两个很大的选择.
- 聪明或类似的模板引擎.或您自己的非php模板引擎.
- php模板.
此决定将由您的最终用户驱动. Smarty是非常限制的,但是如果您要确保仅在模板中运行批准的代码,则可能是一个可行的选择.此外,允许在应用程序本身中对智能模板进行编辑并不是不安全的.
另一方面,WordPress模板工作得很好的原因之一是它们是纯PHP.他们可以调用WordPress API中暴露的任何方法,甚至可以执行自己的有趣逻辑.如果您期望最终用户在技术上或至少在技术上有能力,那么PHP模板就是必需的.另一方面,如果恶意用户进入管理员位,则允许在应用程序中编辑PHP模板可以打开一个巨大的潜在安全孔.您可能想将编辑限制为文件系统.
虽然这涵盖了HTML的创建,但您还应该考虑CSS.您的最终用户能够直接操纵CSS吗?他们要吗?如果您的默认模板包含足够的语义课程,那么如果他们知道自己在做什么,他们可能会做出很多造型.另一方面,您的最终用户可能不知道CSS是什么,因此他们可能想要哦,例如,采摘配色方案和预先制造的配色方案,以及一个配色方案选择器,以及其他令人讨厌的东西要构建.现在最好考虑这些恐怖.
其他东西.
没有草稿概念和发布州的概念,CMS将是完整的.除了代码,我在这里没有任何建议.如果您的客户或最终用户想要任何形式的历史归档,管理批准机制,或其他任何使草稿/出版任何简单国家领域的任何东西,您需要很快就知道. (这是我的咬伤.我们已经围绕一个简单发布/未发布的模型设计了整个系统,并且当我们意识到它无法正常工作时,通过规格构建和相关的原型代码获得了大约9/10.我们必须做一些事情要花更复杂的事情才能真正满足客户的要求.重建粗略的计划是我们迄今为止遇到的最大的时间限制.)
您会使用ORM吗?如果没有,请确保使用适当的数据库接口库. PDO,或者可能是梨中的东西,或者Zend_db.您将不可避免地会有一个客户坚持认为该代码在Oracle或MSSQL上运行.或sqlite.很高兴告诉他们可以做到这一点(付出一些努力).插件作者也将感谢您的理智. 不要自己滚动.
(再说一遍,随着您的代表级别,我希望您已经熟悉了我所说的一切. )
问题描述
I have been given a new task from the client which is basically creating a CMS for actors/singers and the like that client will be selling out to them.
It will basically be a package and would work out-of-box pretty much similar to WordPress, you just hand over to whoever buys it but of course this is not going to be a blogging platform. It will allow developers to:
- Add plugins/widgets
- Add templates/themes
I thought the Observer Pattern may be useful but I am not that sure about it. What you guys could suggest to create such flexible/extensible CMS in terms of:
- Ability to add plugins (for example like WordPress)
- Ability to add themes/templates (for example like WordPress)
- Design Pattern
- Any other things
推荐答案
Observer's fine, but you're going to have to consider going beyond the basic pattern. The canonical Observer/Subject pattern only sends the Subject object to the Observer, nothing else, not even why it's being notified.
Initially, the solution might seem like also including the reason for the notification to the Observer, but then you might end up notifying Observers that don't care about certain notifications. A better solution might be requiring Observers to also ask for a list of notifications they'd like to receive.
But that also presents a problem. In order for the Observers to actually attach themselves to Subjects, they have to be instantiated. Every single time. Even if they'd never be needed. That's silly.
So, we've quickly reached one of the canonical PHP implementations of plugins: "hooks". Hooks use the same concept as Observer/Subject, but the implementation is different in a very important way: the actual Observers aren't instantiated in order to Observe Subjects. Instead, Subjects send a notification to some variety of central repository. This repository is configured with a list of all installed and activated plugins (Observers), and contains a list of all of the events that each plugin wants to receive. Each plugin and notified only when the event takes place, often through a static method rather than by creating an instance of the plugin and notifying it. call_user_func_array and a good autoloader makes this incredibly trivial.
You can therefore create a simple Interface for all plugins to implement. Methods that you'll need include but are not limited to:
- Something to fetch data about the plugin, such as it's name, author, official website, version, etc. Human-consumable information.
- A method returning the events that the plugin wants to subscribe to.
- An installation method, for things the plugin needs to do in order to install itself, such as manipulating the database.
- An uninstallation method might be handy as well.
- The (probably static) method that will receive event notifications and return whatever data is needed.
Depending on how far you take the plugin concept, you could end up with plugins that have user configurable options. You might need to take that into account. Down that road lies madness and configuration systems.
In order to make plugins effective, you're going to need to place hooks everywhere, and frequently work with end-users to add new hooks where they are needed.
Widgets can easily work in a similar way, as plugins that get called prior to page rendering.
Themes/templates, oh my. You probably have two big options.
- Smarty, or a similar template engine. Or your own not-PHP template engine.
- PHP templates.
This decision will be driven by your end users. Smarty is incredibly limiting, but if you want to make sure that only approved code runs in a template, it might be a viable option. Furthermore, it's not unsafe to allow editing of Smarty templates right in the application itself.
On the other hand, one of the reason Wordpress templates work so well is that they're pure PHP. They can call any method exposed in the Wordpress API, and even do their own interesting logic. If you expect your end users to be technically minded, or at least technically competent, then PHP templates are the way to go. On the other hand, allowing editing of PHP templates within the application can open up a huge potential security hole if a malicious user gets into the admin bits. You probably want to restrict editing to the filesystem.
While this covers HTML creation, you should also take CSS into consideration. Will your end-users be able to manipulate CSS directly? Will they want to? If your default templates include enough semantic classes, they can probably do a great deal of styling with not a lot of effort, if they know what they're doing. On the other hand, your end-users might not know what CSS is, so they might want, oh, say, color pickers and pre-built color schemes, and a color scheme chooser, and other such annoying things to build. It's probably best to think about those horrors now.
Miscellaneous things.
No CMS would be complete without the concept of drafts and publish states. I don't have any advice for you here, other than code this first. If your customer or the end-users want any sort of historical archiving, managerial approval mechanism, or anything else that makes draft/published anything but a simple state field, you need to know very soon. (I've been bitten horribly by this one. We'd designed the entire system around a simple published/not-published model, and got about 9/10ths through spec building and related prototype code when we realized it wouldn't work and we'd have to do something far, far more complex to actually meet customer requirements. Rebuilding the rough plan was the single largest time-sink we encountered so far.)
Will you use an ORM? If not, be sure to use a proper database interface library. PDO, or maybe something from PEAR, or maybe Zend_Db. You'll inevitably have a customer that will insist that the code runs on Oracle or MSSQL. Or SQLite. It'll be nice to tell them it can be done (with some effort). Plugin authors will thank you for the sanity as well. Don't roll your own.
(Then again, with your rep level, I expect that you're already familiar with pretty much everything I've said. Ah, the things I do to distract myself while thinking about my own set of coding problems...)