Compare commits

..

49 Commits

Author SHA1 Message Date
7c1d1325eb Adapt to EWF concurrent version. 2015-04-02 18:38:12 +02:00
8382edf9d7 Adapted ROC cms library and example to upcoming concurrency compliant EWF.
(SCOOP support)
2015-03-25 22:32:10 +01:00
e94d860fd8 Commented "mysql" support to make it easier to compile at first. 2015-03-20 19:45:14 +01:00
bd6524ebe7 Fixed issue with ini config component and include functionality.
Added {CMS_SETUP}.cms_config_ini_name to define the CMS Configuration file name,
   and provide an easy way to change the name.
2015-03-09 19:27:30 +01:00
ca10c57b4b Added is_https: BOOLEAN query to CMS (on page, but also as 'is_https' value) 2015-02-16 20:14:45 +01:00
8d59d25ace Added weight into to the CMS_LINK and provide a `sort' feature for CMS_MENU and related.
Protected cms service from registering many time the same module type.
Moved library/persistence/implementation/* under library/persistence/.
Moved site/www/themes to site/themes
For SQLite storage driver, auto create sqlite db file using associated sql script (to be completed).
Added code in demo module to reuse storage for module purpose.
Always call sql_post_execution in sql_query and sql_change, and not anymore by the callers.
Removed is_web and is_html from {CMS_SETUP}, it was not used.
Reused SHARED_*_ENCODER in CMS_ENCODERS
Added CMS_API.logger rather than using directly the SHARED_LOGGER.log ...
Centralize the implementation of current_user in CMS_REQUEST_UTIL
Removed the inheritance on WSF_FILTER for node handlers, since it is useless and unused.
Added CMS_NODE_API and CMS_USER_API
Prefix html id for block generated html items with "block-", to avoid css name conflict on "main", "content" or similar.
Code cleaning
2015-02-16 13:01:06 +01:00
a810b1176c Revisited application layout, shared logger and relation with cms to avoid mixing various layout. 2015-02-05 10:28:46 +01:00
Jocelyn Fiat
e40f8ee4d2 Fixed location of logs folder. 2015-02-03 19:25:38 +01:00
Jocelyn Fiat
83af7f6a38 Fixed shared logger code (there was an issue on non Windows machine)
Now, it is possible to set logs folder from config file.
2015-02-03 19:19:27 +01:00
02368fe3d2 Removed unused local variable.
Updated SHARED_LOGGER to remove a few obsolete calls on json parser.
2015-01-30 19:40:10 +01:00
be0b5c23d2 Added debug output to CMS_BLOCK.
Updated SHARED_LOGGER to remove a few obsolete calls on json parser.
Added favicon.ico specific handling.
Fixed issue with theme and non raw block.
2015-01-30 19:37:12 +01:00
jvelilla
88ec1452d8 Added the new Schema for MySQL 2015-01-29 12:10:01 -03:00
5ddc2006e2 Moved library/src to src 2015-01-27 19:58:13 +01:00
d97c4b1a4a Merge branch 'master' of https://github.com/EiffelWebFramework/ROC 2015-01-27 19:49:49 +01:00
7d5869f3b9 Revisited the persistence layer.
Simplified schema to focus on user and node.
Now possible to have sqlite via ODBC and/or mysql support, and select using configuration file.
Updated demo example.
2015-01-27 19:48:37 +01:00
jvelilla
8c74c7a268 Updated log directory location if the argument `-d' is present. 2015-01-14 20:55:24 -03:00
db9e40cec4 Updated CMS_SERVICE to make the cms library complete void-safe.
Reviewed configuration related feature.
Renamed JSON_CONFIGURATION as APPLICATION_JSON_CONFIGURATION_HELPER to avoid confusion.
Updated CMS_DEFAULT_SETUP to use configuration from cms configuration library.
Added {CMS_API}.module_configuration (a_module_name: READABLE_STRING_GENERAL; a_name: detachable READABLE_STRING_GENERAL): detachable CONFIG_READER  to help getting access to configuration of a module (for now, only json and ini are supported, but in the future, this could support database layer directly)
Added CMS_HOOK_BLOCK_HELPER to reuse the template_block (..): ... function.
Cosmetic
Removed CMS_SETUP.smtp_server since for now, there is no need for such general setting.
Add header line "X-ServerEWF-App: CMS" as a simple way to know if request is processed by the CMS.
2015-01-14 18:25:26 +01:00
Javier Velilla
792880aa7a Update Module implementation 2015-01-02 10:43:17 -03:00
Javier Velilla
5ad8c680a6 Add your own Module 2014-12-31 08:06:54 -03:00
jvelilla
e2f02953f4 Refactor rename error_500_cms_response to internal_server_error_cms_response
Added bad_request_error_cms_response
Updated code example to use the new internal_server_error_cms_response instead of error_500_cms_response class.
Removed class error_500_cms_response.

Updated cms setup and configuration design:
  Removed CMS_SETUP.configuration: CMS_CONFIGURATION
  Removed CMS_CONFIGURATION and replaced it by using the configuration library.
  Added CMS_DEFAULT_SETUP.configuration: CONFIG_READER
  Addec CMS_SETUP.text_item (name): detachable READABLE_STRING_32 ...
    in order to access option not publish by the CMS_SETUP interface.
Removed CMS_SERVICE.configuration: CMS_CONFIGURATION since it was not used.

Moved configuration library from eiffel-lang to cms libraries.
Fixed issue related to ini config when parsing from string content,
  and also issue related to section included in file via @include.
Updated cms setup and configuration design:
  Removed CMS_SETUP.configuration: CMS_CONFIGURATION
  Removed CMS_CONFIGURATION and replaced it by using the configuration library.
  Added CMS_DEFAULT_SETUP.configuration: CONFIG_READER
  Addec CMS_SETUP.text_item (name): detachable READABLE_STRING_32 ...
    in order to access option not publish by the CMS_SETUP interface.
Removed CMS_SERVICE.configuration: CMS_CONFIGURATION since it was not used.
Improved the email service and related.
2014-12-19 18:03:52 -03:00
jvelilla
bd26deb6c1 Updated cms configuration file with an smtp server property.
Updated cms code to use the new property.
Removed title from the home response.
2014-12-17 09:16:19 -03:00
jvelilla
a9109ca8f7 Updated CMS_SMARTY_TEMPALTE_BLOCK, redefined out to be used by the logger.
Updated CMS_API, added wrapper features to access error_handler. has_error, reset, as_string_representation, hide
the actual error hanlder implementation.
Updated Error Filter with better logging.
2014-11-26 13:57:04 -03:00
09e5dc4032 Removed a few obsolete calls related to JSON library.
+ cosmetic
2014-11-20 15:14:34 +01:00
d082326784 Removed useless CMS_CUSTOM_SETUP. 2014-11-20 14:57:19 +01:00
51462829c7 reverted renaming to use `modules' for available modules.
Added CMS_SETUP.register_module (m) to avoid extending directly to the CMS_SETUP.modules
2014-11-20 14:53:54 +01:00
ba58fcdf75 Updated cms library with comments, and removed a few JSON obsolete calls. 2014-11-20 14:11:28 +01:00
Javier Velilla
d84f164dbd Update concepts.md
Updated concepts
2014-11-19 13:20:53 -03:00
jvelilla
c3d022ce46 Refactor raname {CMS_SETUP}.modules as {CMS_SETUP}.available_modules
Refactor raname {CMS_SETUP}.modules_enabled as {CMS_SETUP}.enabled_modules
Updated code to use the new features names.
2014-11-19 13:20:07 -03:00
jvelilla
aac01e093a Added {CMS_SETUP}.modules_enabled: CMS_MODULE_COLLECTION
Updated {CMS_SERVIDE}.intialize_modules to use the new feature {CMS_SETUP}.modules_enabled
Updated cms_hook_block description
2014-11-19 12:13:07 -03:00
jvelilla
fb62a1bb3e Merge branch 'roc_template' of https://github.com/jvelilla/ROC into roc_template 2014-11-19 11:50:56 -03:00
Javier Velilla
6162432d52 Update concepts.md
Updated Concepts table of contents
2014-11-19 11:32:59 -03:00
Javier Velilla
ebed52ae01 Update concepts.md
Updated concepts with Modules and Hooks
2014-11-19 11:16:02 -03:00
b58eeeac26 Added comments. 2014-11-19 13:34:42 +01:00
jvelilla
9169bdcd43 Removed shared_error from CMS_API
Added Missing theme and Missing tempalte classes.
Updated CMS_RESPONSE to handle missing template and send a 503 status code
with a raw response.
2014-11-19 09:22:31 -03:00
jvelilla
e36465f86d Update concepts.md
Added references to the important classes.
2014-11-18 09:26:52 -03:00
76190de218 Fixed non void-safe compilations, and cleaned .ecf files.
+Cosmetic
2014-11-18 10:05:50 +01:00
jvelilla
0edff7853b Removed default_theme.
Update theme and smarty theme description
2014-11-17 22:37:10 -03:00
jvelilla
e20a7af301 Merge pull request #15 from jvelilla/roc_template
Roc template
2014-11-17 13:08:33 -03:00
jvelilla
089b367c95 Update concepts.md
Updated default regions
2014-11-17 13:08:01 -03:00
jvelilla
503f2faf08 Update concepts.md
Updated
2014-11-17 13:03:13 -03:00
jvelilla
b887c13664 Renamed files and added tutorial document 2014-11-17 12:44:37 -03:00
jvelilla
bbfe063b5c Update CMS_concepts.md
Added table of contents
2014-11-17 12:26:58 -03:00
jvelilla
1a4e2935da Update README.md
Update readme file
2014-11-17 12:23:37 -03:00
jvelilla
c3a582f85c Added cms_concepts 2014-11-17 12:10:51 -03:00
8bfb66af30 Added cms_smarty_template_block
Added CMS_RESPONSE.module_assets_location and CMS_RESPONSE.module_assets_theme_location
    that help locating module related assets.
Added CMS_BLOCK.is_raw to abstract CMS_CONTENT_BLOCK.is_raw
2014-11-14 19:31:40 +01:00
6aad460b11 Updated ecf files, and added non void-safe .ecf files. 2014-11-14 14:20:01 +01:00
jvelilla
0dc12b82b8 Merge pull request #14 from jvelilla/roc_template
Update sqlite implemenation to make it compile
2014-11-14 08:26:06 -03:00
jvelilla
8047880c2b Update sqlite implemenation to make it compile 2014-11-13 23:46:02 -03:00
jvelilla
48283742aa Merge pull request #13 from jocelyn/minor_changes_20141113
Renamed {CMS_SETUP} theme_resource_location as theme_assets_location
2014-11-13 15:28:39 -03:00
277 changed files with 7669 additions and 7325 deletions

3
.gitignore vendored
View File

@@ -1,4 +1,5 @@
EIFGENs
*.swp
*.log*
*.rc
*.rc
*.bak

View File

@@ -25,7 +25,10 @@ The goal of the library is to provide the following features.
- doc -- Documentation.
**Documentation**
>[CMS design](https://github.com/EiffelWebFramework/ROC).
>[CMS concepts](https://github.com/EiffelWebFramework/ROC).
>[CMS concepts](/doc/concepts.md).
>[CMS design](/doc/design.md).
>[CMS tutorial](/doc/tutorial.md).

View File

@@ -2,27 +2,26 @@
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="cms" uuid="8CC0D052-57D1-4CAA-AFF1-448FA290734B" library_target="cms">
<target name="cms">
<root all_classes="true"/>
<option warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="transitional" syntax="transitional">
<option warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="all" syntax="transitional">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="config" location=".\library\configuration\config-safe.ecf"/>
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto-safe.ecf"/>
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
<library name="encoder" location="$EWF_LIBRARY\library\text\encoder\encoder-safe.ecf" readonly="false"/>
<library name="error" location="$EWF_LIBRARY\library\utility\general\error\error-safe.ecf"/>
<library name="http" location="$EWF_LIBRARY\library\network\protocol\http\http-safe.ecf"/>
<library name="http_authorization" location="$EWF_LIBRARY\library\server\authentication\http_authorization\http_authorization-safe.ecf" readonly="false"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
<library name="layout" location=".\library\layout\layout-safe.ecf"/>
<library name="model" location=".\library\model\cms_model-safe.ecf" readonly="false"/>
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf" readonly="false"/>
<library name="text_filter" location="$ISE_LIBRARY\unstable\library\text\text_filter\text_filter-safe.ecf"/>
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error-safe.ecf"/>
<library name="http_authorization" location="$ISE_LIBRARY\contrib\library\network\authentication\http_authorization\http_authorization-safe.ecf" readonly="false"/>
<library name="persistence_mysql" location=".\library\persistence\implementation\mysql\persistence_mysql-safe.ecf" readonly="false"/>
<library name="cms_model" location=".\library\model\cms_model-safe.ecf" readonly="false"/>
<library name="smarty" location="$ISE_LIBRARY\contrib\library\text\template\smarty\smarty-safe.ecf" readonly="false"/>
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/>
<library name="wsf_html" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf_html\wsf_html-safe.ecf" readonly="false"/>
<library name="text_filter" location="$ISE_LIBRARY\unstable\library\text\text_filter\text_filter-safe.ecf"/>
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
<cluster name="src" location=".\library\src\" recursive="true">
<library name="wsf" location="$EWF_LIBRARY\library\server\wsf\wsf-safe.ecf"/>
<library name="wsf_extension" location="$EWF_LIBRARY\library\server\wsf\wsf_extension-safe.ecf" readonly="false"/>
<library name="wsf_html" location="$EWF_LIBRARY\library\server\wsf_html\wsf_html-safe.ecf" readonly="false"/>
<cluster name="src" location=".\src\" recursive="true">
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>

32
cms.ecf Normal file
View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="cms" uuid="8CC0D052-57D1-4CAA-AFF1-448FA290734B" library_target="cms">
<target name="cms">
<root all_classes="true"/>
<option warning="true" full_class_checking="false" void_safety="none" syntax="transitional">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="config" location=".\library\configuration\config.ecf"/>
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto.ecf"/>
<library name="encoder" location="$EWF_LIBRARY\library\text\encoder\encoder.ecf" readonly="false"/>
<library name="error" location="$EWF_LIBRARY\library\utility\general\error\error.ecf"/>
<library name="http" location="$EWF_LIBRARY\library\network\protocol\http\http.ecf"/>
<library name="http_authorization" location="$EWF_LIBRARY\library\network\authentication\http_authorization\http_authorization.ecf" readonly="false"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
<library name="layout" location=".\library\layout\layout.ecf"/>
<library name="cms_model" location=".\library\model\cms_model.ecf" readonly="false"/>
<library name="smarty" location="$ISE_LIBRARY\contrib\library\text\template\smarty\smarty.ecf" readonly="false"/>
<library name="text_filter" location="$ISE_LIBRARY\unstable\library\text\text_filter\text_filter.ecf"/>
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
<library name="wsf" location="$EWF_LIBRARY\library\server\wsf\wsf.ecf"/>
<library name="wsf_extension" location="$EWF_LIBRARY\library\server\wsf\wsf_extension.ecf" readonly="false"/>
<library name="wsf_html" location="$EWF_LIBRARY\library\server\wsf_html\wsf_html.ecf" readonly="false"/>
<cluster name="src" location=".\src\" recursive="true">
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
</cluster>
</target>
</system>

View File

93
doc/concepts.md Normal file
View File

@@ -0,0 +1,93 @@
CMS Concepts
============
>Current implemented concepts
##### Table of Contents
1. [**Theme**](#theme)
2. [**Regions**](#regions)
- [**Default Page Layout**](#page_layout)
- [**Regions Holds blocks**](#regions_blocks)
3. [**Blocks**](#blocks)
4. [**Modules**](#modules)
5. [**Hooks**](#hooks)
<a name="theme"/>
Theme
-----
In a CMS , a theme is a collection of templates files (HTML, CSS, Images, etc ) that determine how a CMS web site looks. The goal of a theme is to let you change the look and feel of the site.
Eiffel CMS is inspired by Drupal, and use the same default region names as default drupal theme.
#### Important Classes
* [CMS_THEME] (/library/src/theme/cms_theme.e): Abstraction defining the interface of a CMS theme.
* [SMARTY_CMS_THEME] (/library/src/theme/smarty_theme/smarty_cms_theme.e): Theme implemented using the [Eiffel Smarty library] (https://github.com/eiffelhub/template-smarty).
* [CMS_TEMPLATE] (/library/src/theme/cms_template.e): Template Abstraction that contains theme, variables needed by template when rendering page as html. At the moment there is only one implementation SMARTY_CMS_PAGE_TEMPLATE. At the moment there is only one implementation [SMARTY_CMS_PAGE_TEMPLATE] (/library/src/theme/smarty_theme/smarty_cms_page_template.e).
<a name="regions"/>
Regions
-------
The layout of a CMS web page has predefined area called **regions**. The Eiffel CMS uses the same default regions as Drupal, so let's see them in the following image.
<a name="page_layout"/>
![default page layout](http://themery.com/sites/default/files/figure-15-10.png)
```
regions[page_top] = Top
regions[header] = Header
regions[content] = Content
regions[highlighted] = Highlighted
regions[help] = Help
regions[footer] = Footer
regions[first_sidebar] = first sidebar
regions[second_sidebar] = second sidebar
regions[page_bottom] = Bottom
```
<a name="regions_blocks"/>
**A Region holds blocks**
**What goes inside regions?**
Generally, regions hold smaller piece of content called blocks. Blocks hold chunks of content, like the user login form, navigation menu or the information for the footer.
Regions are defined in a configuration file theme.info.
<a name="blocks"/>
CMS_BLOCK
---------
**What is a cms block?**
Blocks are chunk of content that can be created to display whatever you want, and then can be placed in various resgions in your template (theme) layout.
#### Important Classes
* [CMS_BLOCK] (/library/src/kernel/content/cms_block.e): The deferred class CMS_BLOCK provides an abstraction to describe content to be placed inside Regions.
* [CMS_CONTENT_BLOCK] (/library/src/kernel/content/cms_content_block.e): The class CMS_CONTENT_BLOCK describe how to provide generic content.
* [CMS_MENU_BLOCK](/library/src/kernel/content/cms_menu_block.e): The class CMS_MENU_BLOCK describe how to provides a menu of navigational links.
* [CMS_SMARTY_TEMPLATE_BLOCK] (/library/src/kernel/content/cms_smarty_templateblock.e) The class CMS_SMARTY_TEMPLATE_BLOCK describe how to use a CMS block with smarty template file content.
<a name="modules"/>
CMS_MODULES
-----------
**What is a cms module?**
Modules are piece of code that adds one or more features to your web site.
Modules can be plugged and combined to provide a web site customized to your needs. There are modules for many purposes, for example Administratiton, Basic Authentication, etc.
#### Important Classes
* [CMS_MODULE] (/library/src/modules/cms_module.e): The deferred class CMS_MODULE provides an abstraction to describe a generic module that add features to your web site.
* [CMS_RESPONSE](/library/src/service/response/cms_response.e). The deferred class CMS_RESPONSE provide an abstraction to builds the content to get process to render the output.
<a name="hooks">
CMS_HOOK
--------
Hooks is a mechanism which provide a way for modules to interact with each other and extending blocks of the current CMS.
* [CMS_HOOK] (/library/src/hooks/cms_hook.e): The deferred class CMS_HOOK is a marker interface for CMS Hook
* [CMS_HOOK_AUTO_REGISTER] (/library/src/hooks/cms_hook_auto_register.e): The deferred class provides an abstraction that when inheriting from this class, the declared hooks are automatically registered, otherwise, each descendant has to add it to the cms service itself.
* [CMS_HOOK_BLOCK](/library/src/hooks/cms_hook_block.e): The class CMS_HOOK_BLOCK describe a hook providing a way to alter a generic block.
* [CMS_HOOK_FORM_ALTER](/library/src/hooks/cms_hook_form_alter.e): The class CMS_HOOK_FORM_ATLER describe a hook providing a way to alter a form.
* [CMS_HOOK_MENU_ALTER](/library/src/hooks/cms_hook_menu_alter.e): The class CMS_HOOK_MENU_ATLER describe a hook providing a way to alter a menu.
* [CMS_HOOK_MENU_SYSTEM_ALTER](/library/src/hooks/cms_hook_menu_system_alter.e): The class CMS_HOOK_MENU_SYSTEM_ALTER describe a hook providing a way to alter the CMS menu system.
* [CMS_HOOK_VALUE_TABLE_ALTER](/library/src/hooks/cms_hook_value_table_alter.e):: The class CMS_HOOK_VALUE_TABLE_ALTER describe a hook providing a way to alter the value table for a response.

121
doc/tutorial.md Normal file
View File

@@ -0,0 +1,121 @@
CMS Tutorial
============
[Work in progress]
##### Table of Contents
[Getting Started](#init)
[Building your module](#module)
[Lifecycle](#cycle)
<a name="init"/>
Getting Started
-------------
<a name="module"/>
Building your own module
------------------------
A [Module](/doc/concepts.md#modules) as we already describe it, enable us to add functionallity based on your needs.
Here we will describe the basics steps to write your own modules.
* The first thing to do is inherit from the class [CMS_MODULE] () and redefine the register_hooks (2) feature.
* Implement (via inheritance) the needed [Hooks] (/doc/concepts.md#hooks).
* Define the module API through route definition. (1)
* Define the list of block to be handle by the current module (3).
* Render the block (4) (could be defined in Eiffel itself or using a template file (smarty)).
* API implementation (5).
```
class MY_NEW_MODULE
inherit
CMS_MODULE
redefine
register_hooks
end
CMS_HOOK_BLOCK
CMS_HOOK_MENU_SYSTEM_ALTER
create
make
feature {NONE} -- Initialization
make
-- Create current module
do
name := "new module"
version := "1.0"
description := "Eiffel new module"
package := "example"
end
feature -- Access: router
router (a_api: CMS_API): WSF_ROUTER
-- (1) Node router.
do
create Result.make (1)
Result.handle_with_request_methods ("/demo", create {WSF_URI_AGENT_HANDLER}.make (agent handle_demo (a_api, ?, ?)), Result.methods_head_get)
end
feature -- Hooks
register_hooks (a_response: CMS_RESPONSE)
do
-- (2)
a_response.subscribe_to_menu_system_alter_hook (Current)
a_response.subscribe_to_block_hook (Current)
end
block_list: ITERABLE [like {CMS_BLOCK}.name]
do
-- (3) List of block names, managed by current object.
end
get_block_view (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
do
-- (4) Get block object identified by `a_block_id' and associate with `a_response'.
end
menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE)
local
lnk: CMS_LOCAL_LINK
do
create lnk.make ("Demo", "/demo/")
a_menu_system.primary_menu.extend (lnk)
end
feature -- Handler
handle_demo (a_api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE;)
local
r: NOT_IMPLEMENTED_ERROR_CMS_RESPONSE
do
-- (5)
create r.make (req, res, a_api)
r.set_main_content ("NODE module does not yet implement %"" + req.path_info + "%" ...")
r.add_error_message ("NODE Module: not yet implemented")
r.execute
end
end
```
<a name="cycle"/>
Lifecycle
---------

View File

@@ -9,36 +9,50 @@
<option warning="true" full_class_checking="false" is_attached_by_default="true" void_safety="transitional" syntax="transitional">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<setting name="console_application" value="true"/>
<setting name="concurrency" value="scoop"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="cms" location="..\..\cms-safe.ecf" readonly="false"/>
<library name="cms_demo_module" location="modules\demo\cms_demo_module-safe.ecf" readonly="false"/>
<library name="cms_model" location="..\..\library\model\cms_model-safe.ecf" readonly="false"/>
<library name="layout" location="..\..\library\layout\layout-safe.ecf" readonly="false"/>
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/>
<library name="persistence_sqlite" location="..\..\library\persistence\sqlite\persistence_sqlite-safe.ecf" readonly="false"/>
<library name="wsf" location="$EWF_LIBRARY\library\server\wsf\wsf-safe.ecf"/>
<library name="wsf_extension" location="$EWF_LIBRARY\library\server\wsf\wsf_extension-safe.ecf" readonly="false"/>
</target>
<target name="demo_any" extends="common">
<root class="EWF_ROC_SERVER" feature="make_and_launch"/>
<library name="cgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\cgi-safe.ecf"/>
<library name="libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\libfcgi-safe.ecf"/>
<library name="nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\connector\nino-safe.ecf"/>
<setting name="concurrency" value="scoop"/>
<library name="cgi" location="$EWF_LIBRARY\library\server\wsf\connector\cgi-safe.ecf"/>
<library name="libfcgi" location="$EWF_LIBRARY\library\server\wsf\connector\libfcgi-safe.ecf"/>
<library name="nino" location="$EWF_LIBRARY\library\server\wsf\connector\nino-safe.ecf"/>
<library name="standalone" location="$EWF_LIBRARY\library\server\wsf\connector\standalone-safe.ecf"/>
<cluster name="launcher" location=".\launcher\any\" recursive="true"/>
<cluster name="src" location=".\src\" recursive="true"/>
</target>
<target name="demo_standalone" extends="common">
<root class="EWF_ROC_SERVER" feature="make_and_launch"/>
<setting name="concurrency" value="scoop"/>
<library name="default_standalone" location="$EWF_LIBRARY\library\server\wsf\default\standalone-safe.ecf"/>
<cluster name="launcher" location=".\launcher\default\" recursive="true"/>
<cluster name="src" location=".\src\" recursive="true"/>
</target>
<target name="demo_nino" extends="common">
<root class="EWF_ROC_SERVER" feature="make_and_launch"/>
<library name="default_nino" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\nino-safe.ecf"/>
<setting name="concurrency" value="none"/>
<library name="default_nino" location="$EWF_LIBRARY\library\server\wsf\default\nino-safe.ecf"/>
<cluster name="launcher" location=".\launcher\default\" recursive="true"/>
<cluster name="src" location=".\src\" recursive="true"/>
</target>
<target name="demo_cgi" extends="common">
<root class="EWF_ROC_SERVER" feature="make_and_launch"/>
<library name="default_cgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\cgi-safe.ecf"/>
<library name="default_cgi" location="$EWF_LIBRARY\library\server\wsf\default\cgi-safe.ecf"/>
<cluster name="launcher" location=".\launcher\default\" recursive="true"/>
<cluster name="src" location=".\src\" recursive="true"/>
</target>
<target name="demo_libfcgi" extends="common">
<root class="EWF_ROC_SERVER" feature="make_and_launch"/>
<library name="default_libfcgi" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\libfcgi-safe.ecf"/>
<library name="default_libfcgi" location="$EWF_LIBRARY\library\server\wsf\default\libfcgi-safe.ecf"/>
<cluster name="launcher" location=".\launcher\default\" recursive="true"/>
<cluster name="src" location=".\src\" recursive="true"/>
</target>

View File

@@ -1,2 +1,2 @@
port=8099
#verbose=true
port=9090
#verbose=true

View File

@@ -8,10 +8,10 @@ note
revision: "$Revision: 36 $"
class
APPLICATION_LAUNCHER
APPLICATION_LAUNCHER [G -> WSF_EXECUTION create make end]
inherit
APPLICATION_LAUNCHER_I
APPLICATION_LAUNCHER_I [G]
feature -- Custom

View File

@@ -10,24 +10,28 @@ note
revision: "$Revision: 36 $"
deferred class
APPLICATION_LAUNCHER_I
APPLICATION_LAUNCHER_I [G -> WSF_EXECUTION create make end]
inherit
SHARED_EXECUTION_ENVIRONMENT
feature -- Execution
launch (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
launch (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
local
nature: like launcher_nature
do
nature := launcher_nature
if nature = Void or else nature = nature_nino then
launch_nino (a_service, opts)
if nature = Void then
launch_standalone (opts)
elseif nature = nature_standalone then
launch_standalone (opts)
elseif nature = nature_nino then
launch_nino (opts)
elseif nature = nature_cgi then
launch_cgi (a_service, opts)
launch_cgi (opts)
elseif nature = nature_libfcgi then
launch_libfcgi (a_service, opts)
launch_libfcgi (opts)
else
-- bye bye
(create {EXCEPTIONS}).die (-1)
@@ -43,14 +47,16 @@ feature {NONE} -- Access
--| and we could use WSF_DEFAULT_SERVICE_LAUNCHER to configure this at compilation time.
local
p: PATH
l_entry_name: READABLE_STRING_32
ext: detachable READABLE_STRING_32
do
create p.make_from_string (execution_environment.arguments.command_name)
if attached p.entry as l_entry then
ext := l_entry.extension
ext := l_entry.extension
end
if ext /= Void then
if ext.same_string (nature_standalone) then
Result := nature_standalone
end
if ext.same_string (nature_nino) then
Result := nature_nino
end
@@ -61,39 +67,58 @@ feature {NONE} -- Access
Result := nature_libfcgi
end
end
Result := default_nature
end
feature {NONE} -- standalone
nature_standalone: STRING = "standalone"
launch_standalone (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
local
launcher: WSF_STANDALONE_SERVICE_LAUNCHER [G]
do
create launcher.make_and_launch (opts)
end
feature {NONE} -- nino
nature_nino: STRING = "nino"
launch_nino (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
launch_nino (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
local
launcher: WSF_NINO_SERVICE_LAUNCHER
launcher: WSF_NINO_SERVICE_LAUNCHER [G]
do
create launcher.make_and_launch (a_service, opts)
create launcher.make_and_launch (opts)
end
feature {NONE} -- cgi
nature_cgi: STRING = "cgi"
launch_cgi (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
launch_cgi (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
local
launcher: WSF_CGI_SERVICE_LAUNCHER
launcher: WSF_CGI_SERVICE_LAUNCHER [G]
do
create launcher.make_and_launch (a_service, opts)
create launcher.make_and_launch (opts)
end
feature {NONE} -- libfcgi
nature_libfcgi: STRING = "libfcgi"
launch_libfcgi (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
launch_libfcgi (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
local
launcher: WSF_LIBFCGI_SERVICE_LAUNCHER
launcher: WSF_LIBFCGI_SERVICE_LAUNCHER [G]
do
create launcher.make_and_launch (a_service, opts)
create launcher.make_and_launch (opts)
end
feature -- Default
default_nature: STRING
do
Result := nature_standalone
end

View File

@@ -8,10 +8,10 @@ note
revision: "$Revision: 36 $"
class
APPLICATION_LAUNCHER
APPLICATION_LAUNCHER [G -> WSF_EXECUTION create make end]
inherit
APPLICATION_LAUNCHER_I
APPLICATION_LAUNCHER_I [G]
feature -- Custom

View File

@@ -6,19 +6,19 @@ note
you can customize APPLICATION_LAUNCHER
]"
date: "$Date: 2013-06-12 13:55:42 +0200 (mer., 12 juin 2013) $"
revision: "$Revision: 36 $"
date: "$Date: 2015-02-09 22:29:56 +0100 (lun., 09 févr. 2015) $"
revision: "$Revision: 96596 $"
deferred class
APPLICATION_LAUNCHER_I
APPLICATION_LAUNCHER_I [G -> WSF_EXECUTION create make end]
feature -- Execution
launch (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
launch (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
local
launcher: WSF_SERVICE_LAUNCHER
launcher: WSF_DEFAULT_SERVICE_LAUNCHER [G]
do
create {WSF_DEFAULT_SERVICE_LAUNCHER} launcher.make_and_launch (a_service, opts)
create launcher.make_and_launch (opts)
end
end

View File

@@ -13,11 +13,11 @@
<library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension-safe.ecf"/>
<library name="cms" location="..\..\..\..\cms-safe.ecf" readonly="false"/>
<library name="cms_model" location="..\..\..\..\library\model\cms_model-safe.ecf" readonly="false"/>
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
<library name="http" location="$EWF_LIBRARY\library\network\protocol\http\http-safe.ecf"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
<library name="wsf_encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf"/>
<library name="wsf" location="$EWF_LIBRARY\library\server\wsf\wsf-safe.ecf"/>
<library name="wsf_encoder" location="$EWF_LIBRARY\library\text\encoder\encoder-safe.ecf"/>
<cluster name="src" location=".\" recursive="true"/>
</target>
</system>

View File

@@ -1,8 +1,8 @@
note
description: "Summary description for {CMS_DEMO_MODULE}."
author: ""
date: "$Date$"
revision: "$Revision$"
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
revision: "$Revision: 96616 $"
class
CMS_DEMO_MODULE
@@ -36,7 +36,6 @@ feature -- Access: router
-- Node router.
do
create Result.make (2)
map_uri_template_agent (Result, "/demo/", agent handle_demo (?,?,a_api))
map_uri_template_agent (Result, "/demo/{id}", agent handle_demo_entry (?,?,a_api))
end
@@ -85,11 +84,37 @@ feature -- Hooks
feature -- Handler
initialize_module (a_api: CMS_API)
local
sql: STRING
do
if attached {CMS_STORAGE_SQL} a_api.storage as sql_db then
sql_db.sql_query ("select count(*) from tb_demo;", Void)
if sql_db.has_error then
-- Initialize db for demo module
sql := "[
CREATE TABLE "tb_demo"(
"did" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("did">=0),
"name" VARCHAR(100) NOT NULL,
"value" TEXT
);
]"
sql_db.reset_error
sql_db.sql_change (sql, Void)
if sql_db.has_error then
a_api.logger.put_error ("Could not initialize database for demo module", generating_type)
end
end
end
end
handle_demo,
handle_demo_entry (req: WSF_REQUEST; res: WSF_RESPONSE; a_api: CMS_API)
local
r: NOT_IMPLEMENTED_ERROR_CMS_RESPONSE
do
initialize_module (a_api)
create r.make (req, res, a_api)
r.set_main_content ("NODE module does not yet implement %"" + req.path_info + "%" ...")
r.add_error_message ("NODE Module: not yet implemented")

View File

@@ -1,6 +1,11 @@
engine=smarty
site.name=EWF Web CMS
site.email=your@email.com
var-dir=var
files-dir=files
[layout]
root-dir=site/www
themes-dir=site/themes
[site]
name=Eiffel CMS
email=your@email.com
theme=bootstrap
[misc]
smtp=localhost

View File

@@ -0,0 +1,34 @@
BEGIN;
CREATE TABLE "users"(
"uid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("uid">=0),
"name" VARCHAR(100) NOT NULL,
"password" VARCHAR(100) NOT NULL,
"salt" VARCHAR(100) NOT NULL,
"email" VARCHAR(250) NOT NULL,
"status" INTEGER,
"created" DATETIME NOT NULL,
"signed" DATETIME,
CONSTRAINT "name"
UNIQUE("name")
);
CREATE TABLE "users_roles"(
"rid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("rid">=0),
"role" VARCHAR(100) NOT NULL,
CONSTRAINT "role"
UNIQUE("role")
);
CREATE TABLE "nodes"(
"nid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("nid">=0),
"version" INTEGER,
"type" INTEGER,
"title" VARCHAR(255) NOT NULL,
"summary" TEXT NOT NULL,
"content" MEDIUMTEXT NOT NULL,
"author" INTEGER,
"publish" DATETIME,
"created" DATETIME NOT NULL,
"changed" DATETIME NOT NULL
);
COMMIT;

View File

@@ -0,0 +1,53 @@
ul.horizontal li {
display: inline-block;
}
#header #primary.menu ul li {
color: #555;
background-color: #fff;
padding: 10px;
margin: 0;
}
#header #primary.menu ul li a {
color: #555;
text-decoration: none;
}
#header #primary.menu ul li a:hover {
color: black;
}
#header #primary.menu ul.horizontal {
border-bottom: solid 1px #ddd;
}
#header #primary.menu ul.horizontal li {
border-top: solid 3px #fff;
}
#header #primary.menu ul.horizontal li:hover {
background-color: #ffe;
border-top: solid 3px #999;
}
#header #primary.menu ul.horizontal li.active {
font-weight: bold;
border-top: solid 3px #ddd;
background-color: #ddd;
}
#header #primary.menu ul.horizontal li.active:hover {
border-top: solid 3px blue;
}
#content {
margin-left: 20px;
}
.sidebar {
padding: 5px;
margin: 3px;
border: solid 1px #ccc;
}
.sidebar#sidebar_first {
width: 250px;
float: left;
}
.sidebar#sidebar_second {
width: 250px;
float: right;
}

View File

@@ -0,0 +1,57 @@
ul.horizontal {
li {
display: inline-block;
}
}
#header {
#primary.menu {
ul {
li {
color: #555;
a {
color: #555;
text-decoration: none;
&:hover { color: black; }
}
background-color: #fff;
padding: 10px;
margin: 0;
}
&.horizontal {
border-bottom: solid 1px #ddd;
li {
border-top: solid 3px #fff;
&:hover {
background-color: #ffe;
border-top: solid 3px #999;
}
&.active {
font-weight: bold;
border-top: solid 3px #ddd;
background-color: #ddd;
}
&.active:hover {
border-top: solid 3px blue;
}
}
}
}
}
}
#content {
margin-left: 20px;
}
.sidebar {
padding: 5px;
margin: 3px;
border: solid 1px #ccc;
&#sidebar_first {
width: 250px;
float: left;
}
&#sidebar_second {
width: 250px;
float: right;
}
}

View File

@@ -0,0 +1,14 @@
{assign name="debug_enabled" value="True"/}
{if condition="$debug_enabled"}
<ul>
{assign name="kpage" value="page"/}
{assign name="kregions" value="regions"/}
{foreach key="k" item="i" from="$page.variables"}
{unless condition="$k ~ $kpage"}
{unless condition="$k ~ $kregions"}
<li><strong>{$k/}</strong>={$i/}</li>
{/unless}
{/unless}
{/foreach}
</ul>
{/if}

View File

@@ -0,0 +1,77 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- EWF CMS -->
<link rel="stylesheet" href="{$site_url/}/theme/css/style.css">
<!-- bootstrap framework -->
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap-theme.min.css">
<title>{$head_title/}</title>
</head>
<body>
<!-- Page Top -->
{if isset="$region_top"}
{$region_top/}
{/if}
<!-- Body -->
<div class='container-fluid'>
<!-- Page Header -->
<div id="header">
{if isset="$page.primary_nav"}
{$page.primary_nav/}
{/if}
</div>
<!-- General Page Content -->
<div id='content' class='row-fluid'>
<!-- Left Sidebar sidebar_first -->
{unless isempty="$page.region_sidebar_first"}
<div id="sidebar_first" class="sidebar">{$page.region_sidebar_first/}</div>
{/unless}
<!-- Right Sidebar sidebar_second-->
{unless isempty="$page.region_sidebar_second"}
<div id="sidebar_second" class="sidebar">{$page.region_sidebar_second/}</div>
{/unless}
<!-- Highlighted, Help, Content -->
<div class='span8 main'>
<!-- Highlighted Section -->
{unless isempty="$page.region_highlighted"}
<div id="highlighted">{$page.region_highlighted/}</div>
{/unless}
<!-- Help Section -->
{unless isempty="$page.region_help"}
<div id="help">{$page.region_help/}</div>
{/unless}
<!-- Main Content Section -->
{unless isempty="$page_title"}<h1 class="page-title">{$page_title/}</h1>{/unless}
{$page.region_content/}
</div>
</div>
</div>
<!--Page footer -->
{$page.region_footer/}
<!-- Page Bottom -->
{$page.region_bottom/}
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<!--
{include file="debug.tpl"/}
-->
</body>
</html>

View File

@@ -1,36 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
{include file="master2/head.tpl"/}
</head>
<body>
<!-- Site Navigation -->
{include file="master2/site_navigation.tpl"/}
<div class="container">
<hr>
<div class="row">
<main class="main">
{include file="master2/content.tpl"/}
</main>
</div>
</div>
<div id="footer">
<footer class="site-footer">
{include file="master2/footer.tpl"/}
</footer>
</div>
{if condition="$web"}
{include file="master2/optional_enhancement_js.tpl"/}
{/if}
{if condition="$html"}
{include file="master2/optional_enhancement_js.tpl"/}
{/if}
</body>
</html>

View File

@@ -1,40 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
{include file="master2/head.tpl"/}
</head>
<body>
<!-- Site Navigation -->
{include file="master2/site_navigation.tpl"/}
<!--<header class="main-navi">
{include file="master2/header.tpl"/}
</header> -->
<div class="container">
<hr>
<div class="row">
<main class="main">
{include file="master2/content.tpl"/}
</main>
</div>
</div>
<div id="footer">
<footer class="site-footer">
{include file="master2/footer.tpl"/}
</footer>
</div>
{if condition="$web"}
{include file="master2/optional_enhancement_js.tpl"/}
{/if}
{if condition="$html"}
{include file="master2/optional_enhancement_js.tpl"/}
{/if}
</body>
</html>

View File

@@ -1,5 +0,0 @@
<p>You have successfully signed out</p>
You may want to return
Press this neat little button:<a href="{$host/}/">Take Me Home </a>

View File

@@ -1,11 +0,0 @@
<div itemscope itemtype="http://schema.org/ItemList">
<h2 itemprop="name">Top most recent nodes</h2><br>
<meta itemprop="itemListOrder" content="Descending" />
{foreach from="$nodes" item="item"}
<div class="page-header">
<h3><span itemprop="itemListElement"><a href="{$host/}/node/{$item.id/}" rel="node"><strong>{$item.title/}</strong></a></span> <small>{$item.summary/} - {$item.publication_date_output/} </small></h3>
</div>
{/foreach}
</div>

View File

@@ -1,18 +0,0 @@
<h3> Error: {$code/} </h3>
{assign name="status400" value="400"/}
{assign name="status404" value="404"/}
{assign name="status500" value="500"/}
{if condition="$code ~ $status500"}
<p>Internal server error, for the request <strong>{$request/}</string> </p>
{/if}
{if condition="$code ~ $status404"}
<p> Resourse not found, for the request <strong>{$request/}</string> </p>
{/if}
{if condition="$code ~ $status400"}
<p> Bad request, the request <strong>{$request/}</string> is not valid</p>
{/if}

View File

@@ -1,7 +0,0 @@
<small>
<center>
<p class="text-muted"><a href="#" target="_blank" class="info">API Documentation </a>&nbsp;&nbsp;&nbsp;
<a href="#" target="_blank" class="info">Questions? Comments? Let us know! </a></p>
<p>© Copyright 2014 Eiffel Software -- <a href="#" target="_blank" class="info">Privacy Policy</a>
</center>
</small>

View File

@@ -1,10 +0,0 @@
<meta charset="utf-8">
<link rel="icon" href="{$host/}/static/images/favicon.ico">
<title>Eiffel RESTonCMS</title>
{if condition="$web"}
{include file="master2/optional_styling_css.tpl"/}
{/if}
{if condition="$html"}
{include file="master2/optional_styling_css.tpl"/}
{/if}

View File

@@ -1,2 +0,0 @@
<h1>RESTonCMS</h1>
<p>Tagline</p>

View File

@@ -1,5 +0,0 @@
<!--<ul>
<li class="main-navi-item"><a href="">Nav1</a></li>
<li><a href="">Nav2</a></li>
</ul>
-->

View File

@@ -1,5 +0,0 @@
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
{if condition="$web"}
<script src="{$host/}/static/js/roc.js"></script>
{/if}

View File

@@ -1,9 +0,0 @@
{if condition="$html"}
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="http://getbootstrap.com/assets/css/docs.min.css">
{/if}
{if condition="$web"}
<link rel="stylesheet" href="{$host/}/static/css/bootstrap.css">
<link rel="stylesheet" href="{$host/}/static/css/dashboard.css">
{/if}

View File

@@ -1,27 +0,0 @@
<nav id="" class="navbar navbar-default navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="{$host/}" rel="home">Rest on CMS</a>
</div>
<div class="collapse navbar-collapse" id="navbarCollapse">
<ul class="nav navbar-nav">
<li class="ListOfNodes"><a title="Nodes" href="{$host/}/nodes" rel="node">List of Nodes</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
{if isset="$user"}
<li><a>{$user/}</a></li>
<li><a title="Node" href="{$host/}/node" rel="node">New Node</a></li>
<li><a title="Logoff" href="{$host/}/basic_auth_logoff" rel="logoff">Logoff</a></li>
{/if}
{unless isset="$user"}
<li><a title="Login" href="{$host/}/basic_auth_login" rel="login">Login</a></li>
<li><a title="Register" href="{$host/}/user" rel="register">Register</a></li>
{/unless}
</ul>
</div>
</div>
</nav>

View File

@@ -1,8 +0,0 @@
{if isset="$user"}
<a title="Logoff" class="" href="{$host/}/logoff">Logoff</a>
{/if}
{unless isset="$user"}
<a title="Login" class="" href="{$host/}/login">Login</a>
<a title="Register" class="" href="{$host/}/Register">Register</a>
{/unless}
<a title="Nodes" class="" href="{$host/}/nodes">List of Nodes</a>

View File

@@ -1,174 +0,0 @@
{if condition="html"}
<!DOCTYPE html>
<html lang="en">
<head>
{include file="master2/head.tpl"/}
</head>
<body>
{/if}
{unless condition="$web"}
<!-- Site Navigation -->
{include file="master2/site_navigation.tpl"/}
{/unless}
{if condition="html"}
<div class="container">
<hr>
<div class="row">
<main class="main">
{/if}
<div class="bs-docs-example">
{if condition="$web"}
<ul id="myTab" class="nav nav-tabs" role="tablist">
<li class=""><a href="#view" role="tab" data-toggle="tab">View</a></li>
<li class="active"><a href="#edit" role="tab" data-toggle="tab">Edit</a></li>
<li class=""><a href="#delete" role="tab" data-toggle="tab">Delete</a></li>
</ul>
{/if}
{if condition="$html"}
<ul id="myTab" class="nav nav-tabs" role="tablist">
<li class=""><a href="#view" role="tab" data-toggle="tab">View</a></li>
<li class="active"><a href="#edit" role="tab" data-toggle="tab">Edit</a></li>
<li class=""><a href="#delete" role="tab" data-toggle="tab">Delete</a></li>
</ul>
{/if}
<div id="myTabContent" class="tab-content">
<div class="tab-pane" id="view">
{if isset="$node"}
<hr>
<div class="container-fluid">
<div class="row" itemscope itemtype="http://schema.org/Article">
<div class="row">
<div class="col-sm-6 col-md-4 col-lg-3"><h1><span itemprop="name">{$node.title/}</span></h1></div>
</div>
<div class="row">
<div class="col-sm-6 col-md-4 col-lg-3"><span itemprop="text">{$node.content/}<span></div>
</div>
</div>
</div>
{/if}
</div>
<div class="tab-pane fade active in" id="edit">
{if isset="$user"}
<hr>
<div class="container-fluid">
<div class="col-xs-12" itemscope itemtype="http://schema.org/Article">
{if isset="$node"}
<form class="form-inline well" action="{$host/}/node/{$node.id/}" itemprop="url" method="POST">
<input type="hidden" name="method" value="PUT">
{/if}
{unless isset="$node"}
<form class="form-inline well" action="{$host/}/node" itemprop="url" method="POST">
{/unless/}
<fieldset>
<legend>Edit Node</legend>
<div class="span3">
<p>Add or Edit a Node</p>
</div>
<div class="row">
<div class="col-xs-1">
{if isset="$node"}
<label><span itemprop="name"><a href="{$host/}/node/{$node.id/}/title" rel="node">Title:</a></span></label>
{/if}
{unless isset="$node"}
<label><span itemprop="name">Title:</span> </label>
{/unless}
</div>
<div class="col-xs-7">
<input id="title" type="text" class="form-control" name="title" placeholder="Title" required value="{$node.title/}"/>
</div>
</div>
<div class="row">
<div class="col-xs-1">
{if isset="$node"}
<label> <span itemprop="description"><a href="{$host/}/node/{$node.id/}/summary" rel="node">Summary:</a></span></label>
{/if}
{unless isset="$node"}
<label> <span itemprop="description">Summary:</span></label>
{/unless}
</div>
<div class="col-xs-7">
<textarea id="summary" rows="3" class="form-control" cols="100" name="summary" placeholder="Node summary" required>{$node.summary/}</textarea>
</div>
</div>
<div class="row">
<div class="col-xs-1">
{if isset="$node"}
<label> <span itemprop="text"><a href="{$host/}/node/{$node.id/}/content" rel="node">Content</a></span> </label>
{/if}
{unless isset="$node"}
<label> <span itemprop="text">Content:</span> </label>
{/unless}
</div>
<div class="col-xs-7">
<textarea id="content" rows="25" cols="100" class="form-control" name="content" placeholder="Node content" required>{$node.content/}</textarea>
</div>
</div>
<div>
<label>
<span>&nbsp;</span>
<input type="Submit" value="Send" />
</label>
</div>
</fieldset>
</form>
</div>
{/if}
</div>
</div>
<div class="tab-pane" id="delete">
{if isset="$user"}
<hr>
<div class="container-fluid">
{if isset="$node"}
<form action="{$host/}/node/{$node.id/}" method="POST" class="">
<input type="hidden" name="method" value="DELETE">
<fieldset>
<legend>Delete Node</legend>
<div>
<label>
<span>&nbsp;</span>
<input type="Submit" value="Delete" />
</label>
</div>
</fieldset>
</form>
{/if}
</div>
{/if}
</div>
</div>
</div>
{if condition="html"}
</main>
</div>
</div>
{/if}
{if condition="html"}
<div id="footer">
<footer class="site-footer">
{include file="master2/footer.tpl"/}
</footer>
</div>
{include file="master2/optional_enhancement_js.tpl"/}
</body>
</html>
{/if}

View File

@@ -1,70 +0,0 @@
{if condition="html"}
<!DOCTYPE html>
<html lang="en">
<head>
{include file="master2/head.tpl"/}
</head>
<body>
{/if}
{unless condition="$web"}
<!-- Site Navigation -->
{include file="master2/site_navigation.tpl"/}
{/unless}
{if condition="html"}
<div class="container">
<hr>
<div class="row">
<main class="main">
{/if}
<div class="container-fluid">
<div class="col-xs-12" itemscope itemtype="http://schema.org/Article">
<form class="form-inline well" action="{$host/}/node/{$id/}/content" method="POST" class="">
<input type="hidden" name="method" value="PUT">
<fieldset>
<legend>Edit Node Content</legend>
<div class="row">
<div class="col-xs-1">
<label> <span itemprop="text">Content:</span> </label>
</div>
<div class="col-xs-7">
<textarea id="content" rows="25" cols="100" class="form-control" name="content" placeholder="Node content" required>{$node_content/}</textarea>
</div>
</div>
<div>
<label>
<span>&nbsp;</span>
<input type="Submit" value="Update" />
</label>
</div>
</fieldset>
</form>
</div>
</div>
{if condition="html"}
</main>
</div>
</div>
{/if}
{if condition="html"}
<div id="footer">
<footer class="site-footer">
{include file="master2/footer.tpl"/}
</footer>
</div>
{include file="master2/optional_enhancement_js.tpl"/}
</body>
</html>
{/if}

View File

@@ -1,71 +0,0 @@
{if condition="html"}
<!DOCTYPE html>
<html lang="en">
<head>
{include file="master2/head.tpl"/}
</head>
<body>
{/if}
{unless condition="$web"}
<!-- Site Navigation -->
{include file="master2/site_navigation.tpl"/}
{/unless}
{if condition="html"}
<div class="container">
<hr>
<div class="row">
<main class="main">
{/if}
<div class="container-fluid">
<div class="col-xs-12" itemscope itemtype="http://schema.org/Article">
<form class="form-inline well" action="{$host/}/node/{$id/}/summary" method="POST">
<input type="hidden" name="method" value="PUT">
<fieldset>
<legend>Edit Node Summary</legend>
<div class="row">
<div class="col-xs-1">
<label> <span itemprop="text">Summary:</span> </label>
</div>
<div class="col-xs-7">
<textarea id="summary" rows="3" cols="80" name="summary" placeholder="Node summary" required>{$node_summary/}</textarea>
</div>
</div>
<div>
<label>
<span>&nbsp;</span>
<input type="Submit" value="Send" />
</label>
</div>
</fieldset>
</form>
</div>
</div>
{if condition="html"}
</main>
</div>
</div>
{/if}
{if condition="html"}
<div id="footer">
<footer class="site-footer">
{include file="master2/footer.tpl"/}
</footer>
</div>
{include file="master2/optional_enhancement_js.tpl"/}
</body>
</html>
{/if}

View File

@@ -1,70 +0,0 @@
{if condition="html"}
<!DOCTYPE html>
<html lang="en">
<head>
{include file="master2/head.tpl"/}
</head>
<body>
{/if}
{unless condition="$web"}
<!-- Site Navigation -->
{include file="master2/site_navigation.tpl"/}
{/unless}
{if condition="html"}
<div class="container">
<hr>
<div class="row">
<main class="main">
{/if}
<div class="container-fluid">
<div class="col-xs-12" itemscope itemtype="http://schema.org/Article">
<form class="form-inline well" action="{$host/}/node/{$id/}/title" method="POST">
<input type="hidden" name="method" value="PUT">
<fieldset>
<legend>Edit Node Title</legend>
<div class="row">
<div class="col-xs-1">
<label> <span itemprop="text">Title:</span> </label>
</div>
<div class="col-xs-7">
<input id="title" type="text" name="title" placeholder="Title" required value="{$node_title/}"/>
</div>
</div>
<div>
<label>
<span>&nbsp;</span>
<input type="Submit" value="Send" />
</label>
</div>
</fieldset>
</form>
</div>
</div>
{if condition="html"}
</main>
</div>
</div>
{/if}
{if condition="html"}
<div id="footer">
<footer class="site-footer">
{include file="master2/footer.tpl"/}
</footer>
</div>
{include file="master2/optional_enhancement_js.tpl"/}
</body>
</html>
{/if}

View File

@@ -1,52 +0,0 @@
{if condition="html"}
<!DOCTYPE html>
<html lang="en">
<head>
{include file="master2/head.tpl"/}
</head>
<body>
{/if}
{unless condition="$web"}
<!-- Site Navigation -->
{include file="master2/site_navigation.tpl"/}
{/unless}
{if condition="html"}
<div class="container">
<hr>
<div class="row">
<main class="main">
{/if}
<div itemscope itemtype="http://schema.org/ItemList">
<h2 itemprop="name">List nodes</h2><br>
<meta itemprop="itemListOrder" content="Descending" />
{foreach from="$nodes" item="item"}
<div class="page-header">
<h3><span itemprop="itemListElement"><a href="{$host/}/node/{$item.id/}" rel="node"><strong>{$item.title/}</strong></a></span> <small>{$item.summary/} -{$item.publication_date_output/} </small></h3>
</div>
{/foreach}
</div>
{if condition="html"}
</main>
</div>
</div>
{/if}
{if condition="html"}
<div id="footer">
<footer class="site-footer">
{include file="master2/footer.tpl"/}
</footer>
</div>
{include file="master2/optional_enhancement_js.tpl"/}
</body>
</html>
{/if}

View File

@@ -1,100 +0,0 @@
{if condition="html"}
<!DOCTYPE html>
<html lang="en">
<head>
{include file="master2/head.tpl"/}
</head>
<body>
{/if}
{unless condition="$web"}
<!-- Site Navigation -->
{include file="master2/site_navigation.tpl"/}
{/unless}
{if condition="html"}
<div class="container">
<hr>
<div class="row">
<main class="main">
{/if}
<div class="container-fluid">
<div class="col-xs-12" itemscope itemtype="http://schema.org/Person">
<form class="form-inline well" action="{$host/}/user" data-rel="user-register" method="POST" >
<fieldset>
<legend>Register</legend>
<div class="span3">
<p>Register new user</p>
</div>
<div class="row">
<div class="col-xs-2">
<label><span itemprop="name">Username:</span> </label>
</div>
<div class="col-xs-7">
<input id="username" type="text" name="username" placeholder="Username" required/>
</div>
</div>
<div class="row" itemscope itemtype="http://schema.org/Text">
<div class="col-xs-2">
<label><span itemprop="accessCode">Password:</span> </label>
</div>
<div class="col-xs-7">
<input id="password" type="password" name="password" placeholder="Password" required/>
</div>
</div>
<div class="row" itemscope itemtype="http://schema.org/Text">
<div class="col-xs-2">
<label><span itemprop="accessCode">Re-type Password:</span> </label>
</div>
<div class="col-xs-7">
<input id="check_password" type="password" name="check_password" placeholder="Password" required/>
</div>
</div>
<div class="row">
<div class="col-xs-2">
<label><span itemprop="email">Email:</span> </label>
</div>
<div class="col-xs-7">
<input id="email" type="email" name="email" placeholder="Email" required/>
</div>
s</div>
<div>
<label>
<span>&nbsp;</span>
<input type="Submit" value="Send" />
</label>
</div>
</fieldset>
</form>
</div>
</div>
{if condition="html"}
</main>
</div>
</div>
{/if}
{if condition="html"}
<div id="footer">
<footer class="site-footer">
{include file="master2/footer.tpl"/}
</footer>
</div>
{include file="master2/optional_enhancement_js.tpl"/}
</body>
</html>
{/if}

View File

@@ -1,9 +0,0 @@
name=api
engine=smarty
author=jvelilla
version=0.1
regions[header] = Header
regions[content] = Content
regions[footer] = Footer
regions[first_sidebar] = first sidebar
regions[second_sidebar] = second sidebar

View File

@@ -1,84 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>ROC- Layout with defualt Regions</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css">
<style type="text/css">
</style>
<!-- Latest compiled and minified CSS -->
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap-theme.min.css">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
</head>
<body>
<head>
<title>{$head_title/}</title>
</head>
<body>
<!-- Page Top -->
{if isset="$region_top"}
{$region_top/}
{/if}
<!-- Body -->
<div class='container-fluid'>
<!-- Page Header -->
<div id="header">
{if isset="$page.primary_nav"}
{$page.primary_nav/}
{/if}
</div>
<!-- General Page Content -->
<div id='content' class='row-fluid'>
<!-- Left Sidebar sidebar_first -->
{unless empty="$page.region_sidebar_first"}
<div style="float: left;">
{$page.region_sidebar_first/}
</div>
{/unless}
<!-- Highlighted, Help, Content -->
<div class='span8 main'>
<!-- Highlighted Section -->
{$page.region_highlighted/}
<!-- Help Section -->
{$page.region_help/}
<!-- Main Content Section -->
{unless empty="$page_title"}<h1 class="page-title">{$page_title/}</h1>{/unless}
{$page.region_content/}
</div>
<!-- Right Sidebar sidebar_second-->
{unless empty="$page.region_sidebar_second"}
<div style="float: right;">
{$page.region_sidebar_second/}
</div>
{/unless}
</div>
</div>
<!--Page footer -->
{$page.region_footer/}
<!-- Page Bottom -->
{$page.region_bottom/}
</body>
<script type="text/javascript">
</script>
</body>
</html>

View File

@@ -1,108 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>ROC- Layout with defualt Regions</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet">
<style type="text/css">
</style>
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
</head>
<body>
<head>
<title>ROC CMS - A responsive layout</title>
</head>
<body>
<!-- Page Top -->
<!-- Page Header -->
<div class='container-fluid'>
<h1>ROC Layout with Defaul Regions</h1>
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
</button>
<a class="navbar-brand" href="https://www2.eiffel.com/beta" itemprop="home" rel="home">Eiffel Support Site</a>
</div>
<div class="navbar-collapse collapse" itemscope="itemscope" itemtype="https://www2.eiffel.com/beta/profile/esa_api.xml#report" >
<ul class="nav navbar-nav navbar-left">
<li><a href="https://www2.eiffel.com/beta/reports" class="active" itemprop="all" rel="all">Reports</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a href="https://www2.eiffel.com/beta/register" itemprop="register" rel="register">Register</a></li>
<!--<li><a class="login pull-right" data-toggle="modal" data-target="#myModalSignIn">Sign In</a></li> <! Custome Modal -->
<li id="login_pe" ><a href="https://www2.eiffel.com/beta/login" itemprop="login" rel="login">Sign In</a></li> <!-- Custome Modal -->
</ul>
<!--form class="navbar-form navbar-right">
<input type="text" class="form-control" placeholder="Search..."/>
</form -->
</div>
</div>
<div id='content' class='row-fluid'>
<!-- Highlighted-->
<!-- Left Side Bard sidebar_first -->
<div class='span2 sidebar'>
<h3>Left Sidebar</h3>
<ul class="nav nav-tabs nav-stacked">
<li><a href='#'>Another Link 1</a></li>
<li><a href='#'>Another Link 2</a></li>
<li><a href='#'>Another Link 3</a></li>
</ul>
</div>
<!-- Highlighted, Help, Content -->
<div class='span8 main'>
<h1>Highlighted Section</h1>
<h2>Help Section</h2>
<h2>Main Content Section</h2>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum.<p>
<p>Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum. Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima. Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.</p>
</div>
<!-- Left Side Bard sidebar_second-->
<div class='span2 sidebar'>
<h3>Right Sidebar</h3>
<ul class="nav nav-tabs nav-stacked">
<li><a href='#'>Another Link 1</a></li>
<li><a href='#'>Another Link 2</a></li>
<li><a href='#'>Another Link 3</a></li>
</ul>
</div>
</div>
</div>
<!--Page footer -->
<div id="footer">
<small>
<center>
<p class="text-muted"><a href="#" target="_blank" class="info">ROC Documentation </a>&nbsp;&nbsp;&nbsp;
<a href="http://www.eiffel.com/company/contact/" target="_blank" class="info">Questions? Comments? Let us know! </a></p>
<p>© Copyright 2014 Eiffel Software -- <a href="#" target="_blank" class="info">Privacy Policy</a>
</center>
</small>
</div>
<!-- Page Bottom -->
</body>
<script type="text/javascript">
</script>
</body>
</html>

View File

@@ -1,135 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>ROC- Layout with defualt Regions</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css">
<style type="text/css">
</style>
<!-- Latest compiled and minified CSS -->
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap-theme.min.css">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
</head>
<body>
<head>
<title>ROC CMS - A responsive layout</title>
</head>
<body>
<!-- Page Top -->
<!-- Page Header -->
<!-- <div class='container-fluid'>
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button> <a class="navbar-brand" href="#">Eiffel ROC</a>
</div>
<ul class="nav navbar-nav navbar-left">
<li> <a href="#about">Home</a>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li> <a href="#about">About</a>
</li>
<li> <a href="#services">Service</a>
</li>
<li> <a href="#portfolio" class="">Portfolio</a>
</li>
</ul>
</div>
-->
<div class="container-fluid">
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
</button>
<a class="navbar-brand" href="https://www2.eiffel.com/beta" itemprop="home" rel="home">Eiffel Support Site</a>
</div>
<div class="navbar-collapse collapse" itemscope="itemscope" itemtype="https://www2.eiffel.com/beta/profile/esa_api.xml#report" >
<ul class="nav navbar-nav navbar-left">
<li><a href="https://www2.eiffel.com/beta/reports" class="active" itemprop="all" rel="all">Reports</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a href="https://www2.eiffel.com/beta/register" itemprop="register" rel="register">Register</a></li>
<li id="login_pe" ><a href="https://www2.eiffel.com/beta/login" itemprop="login" rel="login">Sign In</a></li> <!-- Custome Modal -->
</ul>
</div>
</div>
</div>
<div id='content' class='row-fluid'>
<!-- Highlighted-->
<!-- Left Side Bard sidebar_first -->
<div class="sidebar col-sm-2 col-md-2">
<h3>Left Sidebar</h3>
<ul class="nav nav-tabs nav-stacked">
<li><a href="#">Another Link 1</a></li>
<li><a href="#">Another Link 2</a></li>
<li><a href="#">Another Link 3</a></li>
</ul>
</div>
<!-- Highlighted, Help, Content -->
<div class="main col-sm-8 col-md-8">
<h1>Highlighted Section</h1>
<h2>Help Section</h2>
<h2>Main Content Section</h2>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum.<p>
<p>Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum. Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima. Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.</p>
</div>
<!-- Left Side Bard sidebar_second-->
<div class="sidebar col-sm-2 col-md-2">
<h3>Right Sidebar</h3>
<ul class="nav nav-tabs nav-stacked">
<li><a href="#">Another Link 1</a></li>
<li><a href="#">Another Link 2</a></li>
<li><a href="#">Another Link 3</a></li>
</ul>
</div>
</div>
</div>
<!--Page footer -->
<div id="footer">
<small>
<center>
<p class="text-muted"><a href="#" target="_blank" class="info">ROC Documentation </a>&nbsp;&nbsp;&nbsp;
<a href="http://www.eiffel.com/company/contact/" target="_blank" class="info">Questions? Comments? Let us know! </a></p>
<p>© Copyright 2014 Eiffel Software -- <a href="#" target="_blank" class="info">Privacy Policy</a>
</center>
</small>
</div>
<!-- Page Bottom -->
</body>
<script type="text/javascript">
</script>
</body>
</html>

View File

@@ -1,12 +0,0 @@
{include file="tpl/page-header.tpl"/}
<div id="main-wrapper">
<div id="main">
<div id="first_sidebar" class="sidebar {if isset="$first_sidebar_css_class"}{$first_sidebar_css_class/}{/if}">{if isset="$first_sidebar"}{$first_sidebar/}{/if}</div>
<div id="content" class="{if isset="$content_css_class"}{$content_css_class/}{/if}">
Welcome ... this is the front page
{if isset="$content"}{$content/}{/if}
</div>
<div id="second_sidebar" class="sidebar {if isset="$second_sidebar_css_class"}{$second_sidebar_css_class/}{/if}">{if isset="$second_sidebar"}{$second_sidebar/}{/if}</div>
</div>
</div>
{include file="tpl/page-footer.tpl"/}

View File

@@ -1,11 +0,0 @@
{include file="tpl/page-header.tpl"/}
<div id="main-wrapper">
<div id="main">
<div id="first_sidebar" class="sidebar {if isset="$first_sidebar_css_class"}{$first_sidebar_css_class/}{/if}">{if isset="$first_sidebar"}{$first_sidebar/}{/if}</div>
<div id="content" class="{if isset="$content_css_class"}{$content_css_class/}{/if}">
{if isset="$content"}{$content/}{/if}
</div>
<div id="second_sidebar" class="sidebar {if isset="$second_sidebar_css_class"}{$second_sidebar_css_class/}{/if}">{if isset="$second_sidebar"}{$second_sidebar/}{/if}</div>
</div>
</div>
{include file="tpl/page-footer.tpl"/}

View File

@@ -1,91 +0,0 @@
/*
* EWF CMS javascript based on JQuery
*/
/**
* Override jQuery.fn.init to guard against XSS attacks.
*
* See http://bugs.jquery.com/ticket/9521
*/
(function () {
var jquery_init = jQuery.fn.init;
jQuery.fn.init = function (selector, context, rootjQuery) {
// If the string contains a "#" before a "<", treat it as invalid HTML.
if (selector && typeof selector === 'string') {
var hash_position = selector.indexOf('#');
if (hash_position >= 0) {
var bracket_position = selector.indexOf('<');
if (bracket_position > hash_position) {
throw 'Syntax error, unrecognized expression: ' + selector;
}
}
}
return jquery_init.call(this, selector, context, rootjQuery);
};
jQuery.fn.init.prototype = jquery_init.prototype;
})();
var EWFCMS = EWFCMS || { };
EWFCMS.toggleFieldset = function(fieldset) {
if ($(fieldset).is('.collapsed')) {
var content = $('> div:not(.action)', fieldset);
$(fieldset).removeClass('collapsed');
content.hide();
content.slideDown( {
duration: 'fast',
easing: 'linear',
complete: function() {
//Drupal.collapseScrollIntoView(this.parentNode);
this.parentNode.animating = false;
$('div.action', fieldset).show();
},
step: function() {
// Scroll the fieldset into view
//Drupal.collapseScrollIntoView(this.parentNode);
}
});
} else {
var content = $('> div:not(.action)', fieldset).slideUp('fast', function() {
$(this.parentNode).addClass('collapsed');
this.parentNode.animating = false;
});
}
};
jQuery(document).ready(function(){
//$('.collapsed').hide();
$('fieldset.collapsible > legend').each(function() {
var fieldset = $(this.parentNode);
// turn legen into clickable link and wrap contents
var text = this.innerHTML;
$(this).empty()
.append($('<a href="#">'+ text + '</a>').click(function() {
var fieldset = $(this).parents('fieldset:first')[0];
if (!fieldset.animating) {
fieldset.animating = true;
EWFCMS.toggleFieldset(fieldset);
}
return false;
}
))
.after($('<div class="fieldset-wrapper"></div>')
.append(fieldset.children(':not(legend):not(.action)')))
.addClass('collapse-processed');
});
$('fieldset.collapsed').each(function() {
$(this).removeClass('collapsed');
EWFCMS.toggleFieldset(this);
});
});
jQuery(document).ready(function(){
$('#tabs').tabs();
});
//jQuery(document).ready(function(){
//$('#second_sidebar').hide();
//});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 786 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 B

View File

@@ -1,251 +0,0 @@
body { margin: 0; background-color: #eeeeff;}
div#header { background-color: #003; color: #fff; border: solid 1px #003; padding: 0px; margin: 0px;}
div#header img#logo { float: left; margin: 5px 15px 5px 10px; }
div#header div#title {font-size: 180%; font-weight: bold; margin-top: 10px; }
ul.horizontal {
list-style-type: none;
}
ul.horizontal li {
display: inline;
padding: 0 5px 0 5px;
}
div#menu-bar li.active {
border: solid 1px #ff0;
color: #ff0;
}
div#menu-bar li:hover {
background-color: #fff;
color: #00f;
}
div#menu-bar li a {
text-decoration: none;
color: #fff;
}
div#menu-bar li:hover a {
color: #00f;
font-style: bold;
}
div#primary-tabs li {
color: #00f;
padding: 2px 5px 2px 5px;
background-color: #eee;
border: solid 1px #ccf;
}
div#primary-tabs li.active {
padding: 2px 7px 1px 7px;
border-top: solid 2px #99f;
border-left: solid 1px #99f;
border-right: solid 1px #99f;
border-bottom: 0;
background-color: #fff;
color: #00f;
}
div#primary-tabs li:hover {
background-color: #fff;
color: #00f;
}
div#primary-tabs li a {
text-decoration: none;
color: #00f;
}
div#primary-tabs li:hover a {
color: #00f;
font-style: bold;
}
div#menu-first { margin-left: 20%; color: #ccf; background-color: #003; }
div#menu-first a { color: #ccf; }
div#menu-second { color: #99f; background-color: #333; }
div#menu-second a { color: #99f; }
div#main-wrapper {
clear: both;
display: block;
height: 0;
}
div#main { margin: 0; padding: 0; clear: both; height:0; display: block; }
div#content {
padding: 5px 3px 5px 20px;
margin-top: 10px;
min-width: 60%;
display: inline;
float: left;
position: relative;
background-color: #ffffff;
padding-bottom: 30px;
}
div#first_sidebar {
width: 20%;
margin: 5px;
padding: 5px;
display: inline;
float: left;
position: relative;
}
div#second_sidebar {
width: 20%;
margin: 5px;
padding: 5px;
display: inline;
float: left;
position: relative;
background-color: #eee;
}
div.sidebar div.block {
margin-bottom: 5px;
padding: 0;
border: dotted 1px #999;
background-color: #fff;
}
div.sidebar div.block div.title {
padding: 3px 3px 3px 3px;
font-weight: bold;
background-color: #dedede;
border-bottom: dotted 1px #999;
}
div.sidebar div.block div.inside {
margin: 3px;
}
div#footer { margin: 10px 0 10px 0; clear: both; display: block; text-align: center; padding: 10px; border-top: solid 1px #00f; color: #fff; background-color: #333;}
div#footer a { color: #ff0; }
form div.error {
border-top: dotted 1px #f00;
border-bottom: dotted 1px #f00;
border-left: solid 3px #f00;
}
div.node div.title {
font-weight: bold;
font-size: 110%;
border-bottom: dotted 1 px #009;
}
div.description {
font-style: italic;
font-color: #999;
}
div.node-wrapper {
margin: 5px 2px 5px 2px;
border: dotted 1px #dddddd;
padding: 5px 3px 5px 3px;
}
div.node div.title {
font-weight: bold;
font-size: 110%;
border-bottom: dotted 1 px #009;
float: left;
}
div.node div.description {
text-align: right;
}
div.node div.inner {
padding: 5px 5px 5px 10px;
border-top: dotted 1px #dddddd;
}
form#user-login {
border: dotted 1px #099;
display: inline-block;
padding: 10px;
margin: 10px;
}
form#user-login>div {
margin-bottom: 10px;
}
form#user-login .input {
float: left;
}
form#user-login img.logo {
}
div#message {
border: solid 1px #fc0;
background-color: #fed;
color: #000;
padding: 5px;
margin: 5px;
}
div#message li {
padding-left: 5px;
margin-left: 3px;
}
div#message li.success {
color: #003300;
background-color: #ccffcc;
}
div#message li.error {
color: #330000;
background-color: #ff9494;
}
div#message li.warning {
color: #aa2200;
background-color: #ffcc99;
}
div.columns {
margin-top: 10px;
display: inline-block;
clear: both;
}
div.columns>* {
padding-left: 10px;
padding-top: 5px;
border-top: dotted 1px #999;
border-left: dotted 1px #999;
margin-left: 1px;
margin-right: 10px;
float: left;
}
/* Link */
a {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
div.menu ul.vertical {
margin: 0;
padding-left: 10px;
list-style-type: none;
}
div.menu ul.vertical ul {
border-left: solid 3px #eee;
list-style-type: none;
margin: 0;
padding-left: 5px;
margin-left: 5px;
margin-bottom: 5px;
}
/* Fieldset and collapsible */
fieldset.collapsible legend a {
padding-left: 15px;
background: url(menu-expanded.png) 5px 75% no-repeat;
}
fieldset.collapsed legend a {
padding-left: 15px;
background: url(menu-collapsed.png) 5px 50% no-repeat;
}
fieldset.collapsed {
border: none;
border-top: dotted 1px #000;
}

View File

@@ -1,10 +0,0 @@
name=smarty
engine=smarty
author=jfiat
version=0.1
;template_dir=templates
regions[header] = Header
regions[content] = Content
regions[footer] = Footer
regions[first_sidebar] = first sidebar
regions[second_sidebar] = second sidebar

View File

@@ -1,6 +0,0 @@
<div id="footer">{if isset="$footer"}{$footer/}{/if}</div>
</div>
</div>
{if isset="$page_bottom"}{$page_bottom/}{/if}
</body>
</html>

View File

@@ -1,14 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="{$language/}" lang="{$language/}" version="XHTML+RDFa 1.0" dir="ltr">
<head>
{if isset="$head"}{$head/}{/if}
<title>{$head_title/}</title>
{if isset="$styles"}{$styles/}{/if}
{if isset="$scripts"}{$scripts/}{/if}
{if isset="$head_lines"}{$head_lines/}{/if}
</head>
<div id="page-wrapper">
<div id="page">
<div id="header">
{$header/}
</div>

View File

@@ -2,8 +2,8 @@ note
description: "[
application service
]"
date: "$Date$"
revision: "$Revision$"
date: "$Date: 2015-02-09 22:29:56 +0100 (lun., 09 févr. 2015) $"
revision: "$Revision: 96596 $"
class
EWF_ROC_SERVER
@@ -16,16 +16,9 @@ inherit
initialize
end
WSF_SERVICE
redefine
execute
end
REFACTORING_HELPER
ARGUMENTS
SHARED_LOGGER
SHARED_EXECUTION_ENVIRONMENT
create
make_and_launch
@@ -43,36 +36,19 @@ feature {NONE} -- Initialization
do
Precursor
create {WSF_SERVICE_LAUNCHER_OPTIONS_FROM_INI} service_options.make_from_file ("demo.ini")
initialize_cms (cms_setup)
end
feature -- Service
cms_service: CMS_SERVICE
-- cms service.
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
do
cms_service.execute (req, res)
end
feature -- Layout
layout: CMS_LAYOUT
-- cms layout.
feature {NONE} -- Launch operation
launcher: APPLICATION_LAUNCHER
launcher: APPLICATION_LAUNCHER [EWF_ROC_SERVER_EXECUTION]
launch (a_service: WSF_SERVICE; opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
launch (opts: detachable WSF_SERVICE_LAUNCHER_OPTIONS)
local
l_retry: BOOLEAN
l_message: STRING
do
if not l_retry then
log.write_debug (generator + ".launch")
launcher.launch (a_service, opts)
launcher.launch (opts)
else
-- error hanling.
create l_message.make (1024)
@@ -92,61 +68,11 @@ feature {NONE} -- Launch operation
l_message.append ("%N%N")
end
-- send email shutdown
log.write_debug (generator + ".launch shutdown")
end
rescue
l_retry := True
retry
end
feature -- CMS Initialization
cms_setup: CMS_CUSTOM_SETUP
do
if attached separate_character_option_value ('d') as l_dir then
log.write_debug (generator + ".cms_setup using a command line argument -d " + l_dir )
create layout.make_with_path (create {PATH}.make_from_string (l_dir))
else
log.write_debug (generator + ".cms_setup using current directory" )
create layout.make_default
end
create Result.make (layout)
setup_storage (Result)
end
initialize_cms (a_setup: CMS_SETUP)
local
cms: CMS_SERVICE
api: CMS_API
do
log.write_debug (generator + ".initialize_cms")
setup_modules (a_setup)
create api.make (a_setup)
create cms.make (api)
cms_service := cms
end
feature -- CMS setup
setup_modules (a_setup: CMS_SETUP)
-- Setup additional modules.
local
m: CMS_MODULE
do
create {BASIC_AUTH_MODULE} m.make
m.enable
a_setup.modules.extend (m)
create {CMS_DEMO_MODULE} m.make
m.enable
a_setup.modules.extend (m)
end
setup_storage (a_setup: CMS_SETUP)
do
debug ("refactor_fixme")
to_implement ("To implement custom storage")
end
end
end

View File

@@ -0,0 +1,57 @@
note
description: "Summary description for {EWF_ROC_SERVER_EXECUTION}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
EWF_ROC_SERVER_EXECUTION
inherit
CMS_EXECUTION
redefine
initialize
end
REFACTORING_HELPER
SHARED_LOGGER
create
make
feature {NONE} -- Initialization
initialize
do
Precursor
end
feature -- CMS setup
setup_modules (a_setup: CMS_SETUP)
-- Setup additional modules.
local
m: CMS_MODULE
do
create {BASIC_AUTH_MODULE} m.make
if not a_setup.module_with_same_type_registered (m) then
m.enable
a_setup.register_module (m)
end
create {CMS_DEMO_MODULE} m.make
m.enable
a_setup.register_module (m)
end
setup_storage (a_setup: CMS_SETUP)
do
debug ("refactor_fixme")
to_implement ("To implement custom storage")
end
-- a_setup.storage_drivers.force (create {CMS_STORAGE_MYSQL_BUILDER}.make, "mysql")
a_setup.storage_drivers.force (create {CMS_STORAGE_SQLITE_BUILDER}.make, "sqlite")
end
end

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="config" uuid="A3762109-D650-40A1-B55A-7D236A17903F" library_target="config">
<target name="config">
<root all_classes="true"/>
<file_rule>
<exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="standard">
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf"/>
<cluster name="src" location=".\src\" recursive="true"/>
</target>
</system>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="config" uuid="A3762109-D650-40A1-B55A-7D236A17903F" library_target="config">
<target name="config">
<root all_classes="true"/>
<file_rule>
<exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="true" is_attached_by_default="false" void_safety="none" syntax="standard">
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf"/>
<cluster name="src" location=".\src\" recursive="true"/>
</target>
</system>

View File

@@ -0,0 +1,10 @@
${NOTE_KEYWORD}
copyright: "2011-${YEAR}, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"

View File

@@ -0,0 +1,121 @@
note
description: "Summary description for {CONFIG_READER}."
author: ""
date: "$Date: 2014-12-18 16:37:11 +0100 (jeu., 18 déc. 2014) $"
revision: "$Revision: 96383 $"
deferred class
CONFIG_READER
inherit
SHARED_EXECUTION_ENVIRONMENT
feature -- Status report
has_item (k: READABLE_STRING_GENERAL): BOOLEAN
-- Has item associated with key `k'?
deferred
end
has_error: BOOLEAN
-- Has error?
--| Syntax error, source not found, ...
deferred
end
feature -- Query
resolved_text_item (k: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
-- String item associated with key `k' and expanded to resolved variables ${varname}.
do
if attached text_item (k) as s then
Result := resolved_expression (s)
end
end
text_item (k: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
-- String item associated with key `k'.
deferred
end
integer_item (k: READABLE_STRING_GENERAL): INTEGER
-- Integer item associated with key `k'.
deferred
ensure
not has_item (k) implies Result = 0
end
feature {NONE} -- Implementation
resolved_items: detachable STRING_TABLE [READABLE_STRING_32]
-- Resolved items indexed by expression.
resolved_expression (exp: READABLE_STRING_GENERAL): STRING_32
-- Resolved `exp' using `Current' or else environment variables.
local
i,n,b,e: INTEGER
k: detachable READABLE_STRING_GENERAL
c: CHARACTER_32
l_resolved_items: like resolved_items
l_text: detachable READABLE_STRING_GENERAL
do
from
i := 1
n := exp.count
create Result.make (n)
until
i > n
loop
c := exp[i]
if i + 1 < n and then c = '$' and then exp[i+1] = '{' then
b := i + 2
e := exp.index_of ('}', b) - 1
if e > 0 then
k := exp.substring (b, e)
l_text := Void
l_resolved_items := resolved_items
if
l_resolved_items /= Void and then
attached l_resolved_items.item (k) as s
then
-- Already resolved, reuse value.
l_text := s
elseif attached text_item (k) as s then
-- has such item
l_text := s
elseif attached execution_environment.item (k) as v then
-- Or from environment
l_text := v
else
l_text := exp.substring (i, e + 1)
end
i := e + 1
Result.append_string_general (l_text)
else
Result.extend (c)
end
else
Result.extend (c)
end
i := i + 1
end
end
feature -- Duplication
sub_config (k: READABLE_STRING_GENERAL): detachable CONFIG_READER
-- Configuration representing a subset of Current for key `k'.
deferred
end
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -0,0 +1,472 @@
note
description: "[
Object parsing a .ini file.
Lines starting by '#', or ';', or "--" are comments
Section are declared using brackets "[section_name]"
Values are declared as "key = value"
List values are declared as multiple lines "key[] = value"
example:
--------------------
[first_section]
one = abc
[second_section]
two = def
lst[] = a
lst[] = b
lst[] = c
[third_section]
three = ghi
table[a] = foo
table[b] = bar
--------------------
Values are accessible from `items' or by section from `sections'
`item' has smart support for '.'
item ("one") -> abc
item ("two") -> def
item ("second_section.two") -> def
item ("table[b]") -> foo
item ("table.b") -> foo
item ("third_section.table[b]") -> foo
item ("third_section.table.b") -> foo
notes:
it is considered that the .ini file is utf-8 encoded
keys are unicode string
values are stored UTF-8 string, but one can use unicode_string_item to convert to STRING_32
Additional features:
- Include other files:
@include=file-to-include
]"
date: "$Date: 2015-03-09 19:25:49 +0100 (lun., 09 mars 2015) $"
revision: "$Revision: 96797 $"
class
INI_CONFIG
inherit
CONFIG_READER
TABLE_ITERABLE [ANY, READABLE_STRING_GENERAL]
SHARED_EXECUTION_ENVIRONMENT
create
make_from_file,
make_from_string,
make_from_items
feature {NONE} -- Initialization
make_from_file (p: PATH)
do
initialize
parse_file (p)
end
make_from_string (a_content: STRING_8)
do
initialize
parse_content (a_content)
end
make_from_items (a_items: like items)
do
initialize
across
a_items as ic
loop
items.force (ic.item, ic.key)
end
end
initialize
-- Initialize data.
do
associated_path := Void
create utf
create items.make (0)
create sections.make (0)
end
reset
-- Reset internal data.
do
has_error := False
items.wipe_out
sections.wipe_out
end
feature -- Status report
has_item (k: READABLE_STRING_GENERAL): BOOLEAN
-- Has item associated with key `k'?
do
Result := item (k) /= Void
end
has_error: BOOLEAN
-- Has error?
--| Syntax error, source not found, ...
feature -- Access: Config Reader
text_item (k: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
-- String item associated with key `k'.
local
obj: like item
do
obj := item (k)
if attached {READABLE_STRING_32} obj as s32 then
Result := s32
elseif attached {READABLE_STRING_8} obj as s then
Result := utf.utf_8_string_8_to_escaped_string_32 (s)
end
end
integer_item (k: READABLE_STRING_GENERAL): INTEGER
-- Integer item associated with key `k'.
do
if attached {READABLE_STRING_GENERAL} item (k) as s then
Result := s.to_integer
end
end
associated_path: detachable PATH
-- If current was built from a filename, return this path.
feature -- Duplication
sub_config (k: READABLE_STRING_GENERAL): detachable CONFIG_READER
-- Configuration representing a subset of Current for key `k'.
do
if attached sections.item (k) as l_items then
create {INI_CONFIG} Result.make_from_items (l_items)
end
end
feature -- Access
item (k: READABLE_STRING_GENERAL): detachable ANY
-- Value associated with key `k'.
local
i: INTEGER
s,sk: detachable READABLE_STRING_GENERAL
do
-- Try first directly in values
Result := items.item (k)
if Result = Void then
--| If there is a dot
--| this could be
--| section.variable
--| variable.name or variable[name]
i := k.index_of ('.', 1)
if i > 0 then
s := k.head (i - 1)
-- then search first in section
if attached sections.item (s) as l_section then
sk := k.substring (i + 1, k.count)
Result := l_section.item (sk)
if Result = Void then
Result := item_from_values (l_section, sk)
end
end
if Result = Void then
i := k.index_of ('.', i + 1)
if i > 0 then
-- There is another dot .. could be due to include
across
sections as ic
until
Result /= Void
loop
s := ic.key
-- If has other dot, this may be in sub sections ...
if s.has ('.') and then k.starts_with (s) and then k[s.count + 1] = '.' then
if attached sections.item (s) as l_section then
sk := k.substring (s.count + 2, k.count)
Result := l_section.item (sk)
if Result = Void then
Result := item_from_values (l_section, sk)
end
end
end
end
end
if Result = Void then
-- otherwise in values object.
Result := item_from_values (items, k)
end
end
else
--| Could be
--| variable[name]
Result := item_from_values (items, k)
end
end
end
items: STRING_TABLE [ANY]
sections: STRING_TABLE [like items]
feature -- Access
new_cursor: TABLE_ITERATION_CURSOR [ANY, READABLE_STRING_GENERAL]
-- Fresh cursor associated with current structure
do
Result := items.new_cursor
end
feature {NONE} -- Implementation
item_from_values (a_values: STRING_TABLE [ANY]; k: READABLE_STRING_GENERAL): detachable ANY
local
i,j: INTEGER
s: READABLE_STRING_GENERAL
do
Result := a_values.item (k)
if Result = Void then
i := k.index_of ('.', 1)
if i > 0 then
s := k.head (i - 1)
if attached {STRING_TABLE [ANY]} a_values.item (s) as l_table then
Result := l_table.item (k.substring (i + 1, k.count))
end
else
i := k.index_of ('[', 1)
if i > 0 then
j := k.index_of (']', i + 1)
if j = k.count then
s := k.head (i - 1)
if attached {STRING_TABLE [ANY]} a_values.item (s) as l_table then
Result := l_table.item (k.substring (i + 1, j - 1))
end
end
end
end
end
end
record_in_section (obj: ANY; k: READABLE_STRING_GENERAL; a_section: READABLE_STRING_GENERAL)
local
v: detachable like items
do
v := sections.item (a_section)
if v = Void then
create v.make (1)
sections.force (v, a_section)
end
v.force (obj, k)
end
parse_content (a_content: STRING_8)
local
i,j,n: INTEGER
s: READABLE_STRING_8
do
last_section_name := Void
from
i := 1
n := a_content.count
until
i > n
loop
j := a_content.index_of ('%N', i)
if j > 0 then
s := a_content.substring (i, j - 1)
i := j + 1
if i <= n and then a_content[i] = '%R' then
i := i + 1
end
else
j := n
s := a_content.substring (i, j)
i := j + 1
end
analyze_line (s, Void)
variant
i
end
last_section_name := Void
rescue
last_section_name := Void
has_error := True
end
parse_file (p: PATH)
do
associated_path := p
last_section_name := Void
import_path (p, Void)
last_section_name := Void
end
import_path (p: PATH; a_section_prefix: detachable READABLE_STRING_32)
-- Import config from path `p'.
local
f: PLAIN_TEXT_FILE
l_last_section_name: like last_section_name
retried: BOOLEAN
l_old_associated_path: like associated_path
do
l_old_associated_path := associated_path
if retried then
has_error := True
else
associated_path := p
l_last_section_name := last_section_name
last_section_name := Void
create f.make_with_path (p)
if f.exists and then f.is_access_readable then
f.open_read
from
until
f.exhausted or f.end_of_file
loop
f.read_line_thread_aware
analyze_line (f.last_string, a_section_prefix)
end
f.close
else
-- File not readable
has_error := True
end
end
last_section_name := l_last_section_name
associated_path := l_old_associated_path
rescue
retried := True
retry
end
analyze_line (a_line: STRING_8; a_section_prefix: detachable READABLE_STRING_32)
-- Analyze line `a_line'.
local
k,sk: STRING_32
v: STRING_8
obj: detachable ANY
lst: LIST [STRING_8]
tb: STRING_TABLE [STRING_8]
i,j: INTEGER
p: PATH
l_section_name: like last_section_name
do
obj := Void
a_line.left_adjust
if
a_line.is_empty
or a_line.is_whitespace
or a_line.starts_with_general ("#")
or a_line.starts_with_general (";")
or a_line.starts_with_general ("--")
then
-- Ignore
elseif a_line.starts_with_general ("[") then
i := a_line.index_of (']', 1)
l_section_name := utf.utf_8_string_8_to_string_32 (a_line.substring (2, i - 1))
l_section_name.left_adjust
l_section_name.right_adjust
if a_section_prefix /= Void then
l_section_name.prepend_character ('.')
l_section_name.prepend (a_section_prefix)
end
last_section_name := l_section_name
else
i := a_line.index_of ('=', 1)
if i > 1 then
k := utf.utf_8_string_8_to_string_32 (a_line.head (i - 1))
k.right_adjust
v := a_line.substring (i + 1, a_line.count)
v.left_adjust
v.right_adjust
if k.is_case_insensitive_equal_general ("@include") then
create p.make_from_string (v)
if not p.is_absolute and attached associated_path as l_path then
p := l_path.parent.extended_path (p)
end
import_path (p, last_section_name)
else
i := k.index_of ('[', 1)
if i > 0 then
j := k.index_of (']', i + 1)
if j = i + 1 then -- ends_with "[]"
k.keep_head (i - 1)
if attached {LIST [STRING_8]} items.item (k) as l_list then
lst := l_list
else
create {ARRAYED_LIST [STRING_8]} lst.make (1)
record_item (lst, k, a_section_prefix)
end
lst.force (v)
obj := lst
elseif j > i then
-- table
sk := k.substring (i + 1, j - 1)
sk.left_adjust
sk.right_adjust
k.keep_head (i - 1)
if attached {STRING_TABLE [STRING_8]} items.item (k) as l_table then
tb := l_table
else
create tb.make (1)
record_item (tb, k, a_section_prefix)
end
tb.force (v, sk)
obj := tb
else
-- Error missing closing ']'
has_error := True
end
else
record_item (v, k, a_section_prefix)
obj := v
end
if attached last_section_name as l_session and then obj /= Void then
record_in_section (obj, k, l_session)
end
end
else
-- Error
has_error := True
end
end
end
record_item (v: ANY; k: READABLE_STRING_32; a_section_prefix: detachable READABLE_STRING_32)
do
if a_section_prefix /= Void then
items.force (v, a_section_prefix + {STRING_32} "." + k)
else
items.force (v, k)
end
end
feature {NONE} -- Implementation
last_section_name: detachable STRING_32
utf: UTF_CONVERTER
invariant
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -0,0 +1,175 @@
note
description: "Object parsing a JSON configuration file."
date: "$Date: 2014-12-18 16:37:11 +0100 (jeu., 18 déc. 2014) $"
revision: "$Revision: 96383 $"
class
JSON_CONFIG
inherit
CONFIG_READER
create
make_from_file,
make_from_string,
make_from_json_object
feature {NONE} -- Initialization
make_from_file (p: PATH)
-- Create object from a file `p'
do
parse (p)
end
make_from_string (a_json: READABLE_STRING_8)
-- Create current config from string `a_json'.
local
l_parser: JSON_PARSER
do
create l_parser.make_with_string (a_json)
l_parser.parse_content
if
l_parser.is_valid and then
attached l_parser.parsed_json_object as j_o
then
make_from_json_object (j_o)
else
has_error := True
end
end
make_from_json_object (a_object: JSON_OBJECT)
-- Create current config from JSON `a_object'.
do
associated_path := Void
json_value := a_object
end
feature -- Status report
has_item (k: READABLE_STRING_GENERAL): BOOLEAN
-- Has item associated with key `k'?
do
Result := item (k) /= Void
end
has_error: BOOLEAN
-- Has error?
--| Syntax error, source not found, ...
feature -- Access: Config Reader
text_item (k: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
-- String item associated with query `k'.
do
if attached {JSON_STRING} item (k) as l_string then
Result := l_string.unescaped_string_32
elseif attached {JSON_NUMBER} item (k) as l_number then
Result := l_number.item
end
end
integer_item (k: READABLE_STRING_GENERAL): INTEGER
-- Integer item associated with key `k'.
do
if attached {JSON_NUMBER} item (k) as l_number then
Result := l_number.item.to_integer
end
end
associated_path: detachable PATH
-- If current was built from a filename, return this path.
feature -- Duplication
sub_config (k: READABLE_STRING_GENERAL): detachable CONFIG_READER
-- Configuration representing a subset of Current for key `k'.
do
if attached {JSON_OBJECT} item (k) as j_o then
create {JSON_CONFIG} Result.make_from_json_object (j_o)
end
end
feature -- Access
item (k: READABLE_STRING_GENERAL): detachable JSON_VALUE
-- Item associated with query `k' if any.
-- `k' can be a single name such as "foo",
-- or a qualified name such as "foo.bar" (assuming that "foo" is associated with a JSON object).
do
if attached json_value as obj then
Result := object_json_value (obj, k.to_string_32)
end
end
feature {NONE} -- Implementation
object_json_value (a_object: JSON_OBJECT; a_query: READABLE_STRING_32): detachable JSON_VALUE
-- Item associated with query `a_query' from object `a_object' if any.
local
i: INTEGER
h: READABLE_STRING_32
do
i := a_query.index_of ('.', 1)
if i > 1 then
h := a_query.head (i - 1)
if attached {JSON_OBJECT} a_object.item (h) as l_obj then
Result := object_json_value (l_obj, a_query.substring (i + 1, a_query.count))
else
-- This is not an object...
Result := Void
end
else
Result := a_object.item (a_query)
end
end
parse (a_path: PATH)
local
l_parser: JSON_PARSER
do
associated_path := a_path
has_error := False
if attached json_file_from (a_path) as json_file then
l_parser := new_json_parser (json_file)
l_parser.parse_content
if
l_parser.is_valid and then
attached l_parser.parsed_json_object as jv
then
json_value := jv
else
has_error := True
end
else
has_error := True
end
end
feature {NONE} -- JSON
json_value: detachable JSON_OBJECT
-- Possible json object representation.
json_file_from (a_fn: PATH): detachable STRING
do
Result := (create {JSON_FILE_READER}).read_json_from (a_fn.name.out)
end
new_json_parser (a_string: STRING): JSON_PARSER
do
create Result.make_with_string (a_string)
end
note
copyright: "2011-2014, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="config_tests" uuid="AD1DE0F7-BC8A-4A17-9A44-56C917BD5604">
<target name="config_tests">
<root class="TEST_CONFIG_READER_SET" feature="default_create"/>
<file_rule>
<exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="transitional" syntax="standard">
</option>
<setting name="concurrency" value="none"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="config" location="..\config-safe.ecf" readonly="false"/>
<library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/>
<tests name="src" location=".\"/>
</target>
</system>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="config_tests" uuid="AD1DE0F7-BC8A-4A17-9A44-56C917BD5604">
<target name="config_tests">
<root class="TEST_CONFIG_READER_SET" feature="default_create"/>
<file_rule>
<exclude>/.git$</exclude>
<exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
<option warning="true" full_class_checking="true" void_safety="none" syntax="standard">
</option>
<setting name="concurrency" value="none"/>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="config" location="..\config.ecf" readonly="false"/>
<library name="testing" location="$ISE_LIBRARY\library\testing\testing.ecf"/>
<tests name="src" location=".\"/>
</target>
</system>

View File

@@ -0,0 +1,177 @@
note
description: "[
Testing suite for CONFIG_READER .
]"
author: "$Author: jfiat $"
date: "$Date: 2014-12-18 16:37:11 +0100 (jeu., 18 déc. 2014) $"
revision: "$Revision: 96383 $"
class
TEST_CONFIG_READER_SET
inherit
EQA_TEST_SET
feature -- Test
test_ini
local
cfg: CONFIG_READER
do
create {INI_CONFIG} cfg.make_from_string ("[
foo = bar
[first]
abc = 1
def = and so on
ghi = "path"
[ second ]
this = 1
is = 2
the = 3
end = 4
]")
assert ("is valid", not cfg.has_error)
assert ("has_item (foo)", cfg.has_item ("foo"))
assert ("has_item (abc)", cfg.has_item ("abc"))
assert ("has_item (def)", cfg.has_item ("def"))
assert ("has_item (ghi)", cfg.has_item ("ghi"))
assert ("has_item (this)", cfg.has_item ("this"))
assert ("has_item (is)", cfg.has_item ("is"))
assert ("has_item (the)", cfg.has_item ("the"))
assert ("has_item (end)", cfg.has_item ("end"))
assert ("item (foo)", attached cfg.text_item ("foo") as v and then v.same_string_general ("bar"))
assert ("item (abc)", attached cfg.text_item ("abc") as v and then v.same_string_general ("1"))
assert ("item (def)", attached cfg.text_item ("def") as v and then v.same_string_general ("and so on"))
assert ("item (ghi)", attached cfg.text_item ("ghi") as v and then v.same_string_general ("%"path%""))
assert ("item (this)", attached cfg.text_item ("this") as v and then v.same_string_general ("1"))
assert ("item (is)", attached cfg.text_item ("is") as v and then v.same_string_general ("2"))
assert ("item (the)", attached cfg.text_item ("the") as v and then v.same_string_general ("3"))
assert ("item (end)", attached cfg.text_item ("end") as v and then v.same_string_general ("4"))
assert ("has_item (first.abc)", cfg.has_item ("first.abc"))
assert ("item (first.abc)", attached cfg.text_item ("first.abc") as v and then v.same_string_general ("1"))
assert ("has_item (second.is)", cfg.has_item ("second.is"))
assert ("item (second.is)", attached cfg.text_item ("second.is") as v and then v.same_string_general ("2"))
if attached cfg.sub_config ("second") as cfg_second then
assert ("has_item (is)", cfg_second.has_item ("is"))
assert ("item (is)", attached cfg_second.text_item ("is") as v and then v.same_string_general ("2"))
else
assert ("has second", False)
end
end
test_resolver_ini
local
cfg: CONFIG_READER
do
create {INI_CONFIG} cfg.make_from_string ("[
foo = bar
[extra]
a.b.c = abc
[expression]
text = ${foo}/${a.b.c}
]")
assert ("is valid", not cfg.has_error)
assert ("has_item (extra.a.b.c)", cfg.has_item ("extra.a.b.c"))
assert ("has_item (extra.a.b.c)", cfg.has_item ("extra.a.b.c"))
assert ("has_item (expression.text)", cfg.has_item ("expression.text"))
assert ("item (expression.text)", attached cfg.resolved_text_item ("expression.text") as s and then s.same_string_general ("bar/abc"))
end
test_deep_ini
local
cfg: CONFIG_READER
f: RAW_FILE
do
create f.make_with_name ("test_deep.ini")
f.create_read_write
f.put_string ("[
test = extra
[new]
enabled = true
]"
)
f.close
create {INI_CONFIG} cfg.make_from_string ("[
foo = bar
[extra]
a.b.c = abc
[outside]
before = include
@include=test_deep.ini
]")
f.delete
assert ("is valid", not cfg.has_error)
assert ("has_item (extra.a.b.c)", cfg.has_item ("extra.a.b.c"))
assert ("has_item (extra.a.b.c)", cfg.has_item ("extra.a.b.c"))
assert ("has_item (outside.new.enabled)", cfg.has_item ("outside.new.enabled"))
end
test_json
local
cfg: CONFIG_READER
do
create {JSON_CONFIG} cfg.make_from_string ("[
{
"foo": "bar",
"first": {
"abc": 1,
"def": "and so on",
"ghi": "\"path\""
},
"second": {
"this": 1,
"is": 2,
"the": 3,
"end": 4
}
}
]")
assert ("is valid", not cfg.has_error)
assert ("has_item (foo)", cfg.has_item ("foo"))
assert ("has_item (first.abc)", cfg.has_item ("first.abc"))
assert ("has_item (first.def)", cfg.has_item ("first.def"))
assert ("has_item (first.ghi)", cfg.has_item ("first.ghi"))
assert ("has_item (second.this)", cfg.has_item ("second.this"))
assert ("has_item (second.is)", cfg.has_item ("second.is"))
assert ("has_item (second.the)", cfg.has_item ("second.the"))
assert ("has_item (second.end)", cfg.has_item ("second.end"))
assert ("item (foo)", attached cfg.text_item ("foo") as v and then v.same_string_general ("bar"))
assert ("item (first.abc)", attached cfg.text_item ("first.abc") as v and then v.same_string_general ("1"))
assert ("item (first.def)", attached cfg.text_item ("first.def") as v and then v.same_string_general ("and so on"))
assert ("item (first.ghi)", attached cfg.text_item ("first.ghi") as v and then v.same_string_general ("%"path%""))
assert ("item (second.this)", attached cfg.text_item ("second.this") as v and then v.same_string_general ("1"))
assert ("item (second.is)", attached cfg.text_item ("second.is") as v and then v.same_string_general ("2"))
assert ("item (second.the)", attached cfg.text_item ("second.the") as v and then v.same_string_general ("3"))
assert ("item (second.end)", attached cfg.text_item ("second.end") as v and then v.same_string_general ("4"))
if attached cfg.sub_config ("second") as cfg_second then
assert ("has_item (is)", cfg_second.has_item ("is"))
assert ("item (is)", attached cfg_second.text_item ("is") as v and then v.same_string_general ("2"))
else
assert ("has second", False)
end
end
end

View File

@@ -2,7 +2,7 @@
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="layout" uuid="7AE9E48B-5A15-43F8-B99A-04F4185DED6B" library_target="layout">
<target name="layout">
<root all_classes="true"/>
<option warning="true">
<option warning="true" void_safety="all">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<setting name="console_application" value="true"/>

21
library/layout/layout.ecf Normal file
View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="layout" uuid="7AE9E48B-5A15-43F8-B99A-04F4185DED6B" library_target="layout">
<target name="layout">
<root all_classes="true"/>
<option warning="true" void_safety="none">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<setting name="console_application" value="true"/>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
<library name="logging" location="$ISE_LIBRARY\library\runtime\logging\logging.ecf"/>
<library name="thread" location="$ISE_LIBRARY\library\thread\thread.ecf"/>
<cluster name="src" location=".\src\" recursive="true">
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
</cluster>
</target>
</system>

View File

@@ -11,15 +11,19 @@ note
- templates (html, Collection+JSON, ...)
- ...
]"
date: "$Date$"
revision: "$Revision$"
date: "$Date: 2015-02-05 10:25:53 +0100 (jeu., 05 févr. 2015) $"
revision: "$Revision: 96584 $"
class
APPLICATION_LAYOUT
inherit
SHARED_EXECUTION_ENVIRONMENT
create
make_default,
make_with_path
make_with_path,
make_with_directory_name
feature {NONE} -- Initialization
@@ -37,6 +41,34 @@ feature {NONE} -- Initialization
-- Create a layour based on a path `p'.
do
path := p.absolute_path.canonical_path
initialize_name
end
make_with_directory_name (a_dirname: READABLE_STRING_GENERAL)
-- Create a layour based on a path `p'.
do
make_with_path (create {PATH}.make_from_string (a_dirname))
end
initialize_name
-- Initialize `name'.
local
p: PATH
s: STRING_32
do
create p.make_from_string (execution_environment.arguments.command_name)
if attached p.entry as e then
p := e
end
create s.make_from_string (p.name)
if attached p.extension as l_extension then
s.remove_tail (l_extension.count + 1)
end
if s.is_whitespace then
set_name ({STRING_8} "app")
else
set_name (s)
end
end
feature -- Access
@@ -44,6 +76,17 @@ feature -- Access
path: PATH
-- Root location.
name: IMMUTABLE_STRING_32
-- Application name, default is "app"
feature -- Change
set_name (a_name: READABLE_STRING_GENERAL)
-- Set `name' from `a_name'.
do
create name.make_from_string_general (a_name)
end
feature -- Access: internal
config_path: PATH
@@ -163,6 +206,6 @@ feature {NONE} -- Implementation
-- Directory for templates (HTML, etc).
;note
copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -0,0 +1,119 @@
note
description: "Provide access to json configuration"
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
class
APPLICATION_JSON_CONFIGURATION_HELPER
feature -- Application Configuration
new_smtp_configuration (a_path: PATH): READABLE_STRING_32
-- Build a new database configuration.
local
l_parser: JSON_PARSER
do
Result := ""
if attached json_file_from (a_path) as json_file then
l_parser := new_json_parser (json_file)
l_parser.parse_content
if
l_parser.is_valid and then
attached {JSON_OBJECT} l_parser.parsed_json_value as jv and then
attached {JSON_OBJECT} jv.item ("smtp") as l_smtp and then
attached {JSON_STRING} l_smtp.item ("server") as l_server
then
Result := l_server.item
end
end
end
new_database_configuration (a_path: PATH): detachable DATABASE_CONFIGURATION
-- Build a new database configuration.
local
l_parser: JSON_PARSER
do
if attached json_file_from (a_path) as json_file then
l_parser := new_json_parser (json_file)
l_parser.parse_content
if
l_parser.is_valid and then
attached {JSON_OBJECT} l_parser.parsed_json_value as jv and then
attached {JSON_OBJECT} jv.item ("database") as l_database and then
attached {JSON_OBJECT} l_database.item ("datasource") as l_datasource and then
attached {JSON_STRING} l_datasource.item ("driver") as l_driver and then
attached {JSON_STRING} l_datasource.item ("environment") as l_envrionment and then
attached {JSON_OBJECT} l_database.item ("environments") as l_environments and then
attached {JSON_OBJECT} l_environments.item (l_envrionment.item) as l_environment_selected and then
attached {JSON_STRING} l_environment_selected.item ("connection_string") as l_connection_string
then
create Result.make (l_driver.item, l_connection_string.unescaped_string_32)
end
end
end
new_logger_level_configuration (a_path: PATH): READABLE_STRING_32
-- Retrieve a new logger level configuration.
-- By default, level is set to `DEBUG'.
local
l_parser: JSON_PARSER
do
Result := "DEBUG"
if attached json_file_from (a_path) as json_file then
l_parser := new_json_parser (json_file)
l_parser.parse_content
if
l_parser.is_valid and then
attached {JSON_OBJECT} l_parser.parsed_json_value as jv and then
attached {JSON_OBJECT} jv.item ("logger") as l_logger and then
attached {JSON_STRING} l_logger.item ("level") as l_level
then
Result := l_level.item
end
end
end
new_database_configuration_test (a_path: PATH): detachable DATABASE_CONFIGURATION
-- Build a new database configuration for testing purposes.
local
l_parser: JSON_PARSER
do
if attached json_file_from (a_path) as json_file then
l_parser := new_json_parser (json_file)
l_parser.parse_content
if
l_parser.is_valid and then
attached {JSON_OBJECT} l_parser.parsed_json_value as jv and then
l_parser.is_parsed and then
attached {JSON_OBJECT} jv.item ("database") as l_database and then
attached {JSON_OBJECT} l_database.item ("datasource") as l_datasource and then
attached {JSON_STRING} l_datasource.item ("driver") as l_driver and then
attached {JSON_STRING} l_datasource.item ("environment") as l_envrionment and then
attached {JSON_STRING} l_datasource.item ("trusted") as l_trusted and then
attached {JSON_OBJECT} l_database.item ("environments") as l_environments and then
attached {JSON_OBJECT} l_environments.item ("test") as l_environment_selected and then
attached {JSON_STRING} l_environment_selected.item ("connection_string") as l_connection_string and then
attached {JSON_STRING} l_environment_selected.item ("name") as l_name
then
create Result.make (l_driver.item, l_connection_string.unescaped_string_8)
end
end
end
feature {NONE} -- JSON
json_file_from (a_fn: PATH): detachable STRING
do
Result := (create {JSON_FILE_READER}).read_json_from (a_fn.name.out)
end
new_json_parser (a_string: STRING): JSON_PARSER
do
create Result.make_with_string (a_string)
end
note
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -1,7 +1,7 @@
note
description: "Object that represent Database configuration settings"
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
revision: "$Revision: 95678 $"
date: "$Date: 2015-02-09 22:29:56 +0100 (lun., 09 févr. 2015) $"
revision: "$Revision: 96596 $"
class
DATABASE_CONFIGURATION
@@ -25,18 +25,73 @@ feature {NONE} -- Initialization
feature -- Access
driver: READABLE_STRING_32
--Database driver.
--Database driver.
database_string: READABLE_STRING_32
-- Database connection.
-- Database connection.
connection_string: READABLE_STRING_32
-- Connection string
do
Result := "Driver={"+driver+"};" + database_string;
Result := {STRING_32} "Driver={" + driver + {STRING_32} "};" + database_string
end
item (a_param: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
local
s: READABLE_STRING_32
lower_s: READABLE_STRING_32
i,j: INTEGER
k: STRING_32
do
create k.make_from_string_general (a_param)
k.to_lower
s := database_string
lower_s := s.as_lower
i := lower_s.substring_index (k + {STRING_32} "=", 1)
if i > 0 then
if i = 1 or else s[i-1] = ';' then
j := s.index_of (';', i + k.count + 1)
if j = 0 then
j := s.count + 1
end
Result := s.substring (i + k.count + 1, j - 1)
end
end
end
server_name: detachable READABLE_STRING_32
do
Result := item ("Server")
end
port: INTEGER
do
if
attached item ("Port") as l_port and then
l_port.is_integer
then
Result := l_port.to_integer
end
end
database_name: detachable READABLE_STRING_32
do
Result := item ("Database")
end
user_id: detachable READABLE_STRING_32
do
Result := item ("Uid")
end
user_password: detachable READABLE_STRING_32
do
Result := item ("Pwd")
end
note
copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -1,103 +0,0 @@
note
description: "Provide access to json configuration"
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
revision: "$Revision: 95678 $"
class
JSON_CONFIGURATION
feature -- Application Configuration
new_smtp_configuration (a_path: PATH): READABLE_STRING_32
-- Build a new database configuration.
local
l_parser: JSON_PARSER
do
Result := ""
if attached json_file_from (a_path) as json_file then
l_parser := new_json_parser (json_file)
if attached {JSON_OBJECT} l_parser.parse as jv and then l_parser.is_parsed and then
attached {JSON_OBJECT} jv.item ("smtp") as l_smtp and then
attached {JSON_STRING} l_smtp.item ("server") as l_server then
Result := l_server.item
end
end
end
new_database_configuration (a_path: PATH): detachable DATABASE_CONFIGURATION
-- Build a new database configuration.
local
l_parser: JSON_PARSER
do
if attached json_file_from (a_path) as json_file then
l_parser := new_json_parser (json_file)
if attached {JSON_OBJECT} l_parser.parse as jv and then l_parser.is_parsed and then
attached {JSON_OBJECT} jv.item ("database") as l_database and then
attached {JSON_OBJECT} l_database.item ("datasource") as l_datasource and then
attached {JSON_STRING} l_datasource.item ("driver") as l_driver and then
attached {JSON_STRING} l_datasource.item ("environment") as l_envrionment and then
attached {JSON_OBJECT} l_database.item ("environments") as l_environments and then
attached {JSON_OBJECT} l_environments.item (l_envrionment.item) as l_environment_selected and then
attached {JSON_STRING} l_environment_selected.item ("connection_string") as l_connection_string then
create Result.make (l_driver.item, l_connection_string.unescaped_string_8)
end
end
end
new_logger_level_configuration (a_path: PATH): READABLE_STRING_32
-- Retrieve a new logger level configuration.
-- By default, level is set to `DEBUG'.
local
l_parser: JSON_PARSER
do
Result := "DEBUG"
if attached json_file_from (a_path) as json_file then
l_parser := new_json_parser (json_file)
if attached {JSON_OBJECT} l_parser.parse as jv and then l_parser.is_parsed and then
attached {JSON_OBJECT} jv.item ("logger") as l_logger and then
attached {JSON_STRING} l_logger.item ("level") as l_level then
Result := l_level.item
end
end
end
new_database_configuration_test (a_path: PATH): detachable DATABASE_CONFIGURATION
-- Build a new database configuration for testing purposes.
local
l_parser: JSON_PARSER
do
if attached json_file_from (a_path) as json_file then
l_parser := new_json_parser (json_file)
if attached {JSON_OBJECT} l_parser.parse as jv and then l_parser.is_parsed and then
attached {JSON_OBJECT} jv.item ("database") as l_database and then
attached {JSON_OBJECT} l_database.item ("datasource") as l_datasource and then
attached {JSON_STRING} l_datasource.item ("driver") as l_driver and then
attached {JSON_STRING} l_datasource.item ("environment") as l_envrionment and then
attached {JSON_STRING} l_datasource.item ("trusted") as l_trusted and then
attached {JSON_OBJECT} l_database.item ("environments") as l_environments and then
attached {JSON_OBJECT} l_environments.item ("test") as l_environment_selected and then
attached {JSON_STRING} l_environment_selected.item ("connection_string") as l_connection_string and then
attached {JSON_STRING} l_environment_selected.item ("name") as l_name then
create Result.make (l_driver.item, l_connection_string.unescaped_string_8)
end
end
end
feature {NONE} -- JSON
json_file_from (a_fn: PATH): detachable STRING
do
Result := (create {JSON_FILE_READER}).read_json_from (a_fn.name.out)
end
new_json_parser (a_string: STRING): JSON_PARSER
do
create Result.make_parser (a_string)
end
note
copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -1,7 +1,7 @@
note
description: "Object that represents Logger configuration settings"
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
revision: "$Revision: 95678 $"
date: "$Date: 2015-02-03 19:11:23 +0100 (mar., 03 févr. 2015) $"
revision: "$Revision: 96575 $"
class
LOGGER_CONFIGURATION
@@ -29,6 +29,7 @@ feature -- Initialization
do
backup_count := 4
level := Log_debug
location := Void
ensure then
backup_count_set: backup_count = 4
level_set: level = Log_debug
@@ -36,6 +37,9 @@ feature -- Initialization
feature -- Access
location: detachable PATH
-- Location for logs files, if none use default logs location.
backup_count: NATURAL
-- Max number of backup files.
-- When 0, no backup files are created, and the log file is simply truncated when it becomes larger than `max_file_size'.
@@ -46,6 +50,21 @@ feature -- Access
feature -- Element Change
set_location (a_location: detachable PATH)
-- Set `location' to `a_location'.
do
location := a_location
ensure
location_set: a_location ~ location
end
set_location_with_string (a_location: READABLE_STRING_GENERAL)
require
a_location /= Void and then not a_location.is_whitespace
do
set_location (create {PATH}.make_from_string (a_location))
end
set_backup_count (a_backup: NATURAL)
-- Set backup_count to `a_backup'.
do
@@ -78,6 +97,6 @@ feature -- Element Change
end
end
note
copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -56,10 +56,10 @@ feature -- Element Settings
l_message.append ("An unknown exception was raised.")
end
set_last_error (l_message, a_location)
log.write_critical (generator + ".set_last_error_from_exception " + l_message)
write_critical_log (generator + ".set_last_error_from_exception " + l_message)
else
set_last_error ("Generic error", "")
log.write_critical (generator + ".set_last_error_from_exception Generic Error")
write_critical_log (generator + ".set_last_error_from_exception Generic Error")
end
rescue
l_retried := True
@@ -75,7 +75,7 @@ feature -- Element Settings
attached_location: a_location /= Void
do
create last_error.make (a_message, a_location)
log.write_critical (generator + ".set_last_error " + a_message)
write_critical_log (generator + ".set_last_error " + a_message)
successful := False
ensure
last_error_set: attached last_error
@@ -103,6 +103,6 @@ feature -- Element Settings
successful: successful
end
note
copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -0,0 +1,172 @@
note
description: "Summary description for {LOGGER}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
LOGGER
inherit
ANY
LOG_PRIORITY_CONSTANTS
export
{NONE} all
end
SHARED_EXECUTION_ENVIRONMENT
export
{NONE} all
end
create
make,
make_with_layout
feature {NONE} -- Initialization
make
do
create log.make
end
make_with_layout (app: APPLICATION_LAYOUT)
do
make
apply_layout (app)
end
feature -- Change
apply_layout (app: APPLICATION_LAYOUT)
do
initialize_logger (app, log)
end
feature {NONE} -- Internal
log: LOGGING_FACILITY
feature -- Logging
put_information (a_message: separate READABLE_STRING_8)
do
log.write_information (create {STRING}.make_from_separate (a_message))
end
put_error (a_message: separate READABLE_STRING_8)
do
log.write_error (create {STRING}.make_from_separate (a_message))
end
put_warning (a_message: separate READABLE_STRING_8)
do
log.write_warning (create {STRING}.make_from_separate (a_message))
end
put_critical (a_message: separate READABLE_STRING_8)
do
log.write_critical (create {STRING}.make_from_separate (a_message))
end
put_alert (a_message: separate READABLE_STRING_8)
do
log.write_alert (create {STRING}.make_from_separate (a_message))
end
put_debug (a_message: separate READABLE_STRING_8)
do
log.write_debug (create {STRING}.make_from_separate (a_message))
end
feature {NONE} -- Implementation
initialize_logger (app: APPLICATION_LAYOUT; a_log: like log)
local
l_log_writer_file: LOG_ROLLING_WRITER_FILE
l_log_writer: LOG_WRITER
l_logs_path: detachable PATH
l_logger_config: LOGGER_CONFIGURATION
ut: FILE_UTILITIES
do
l_logger_config := new_logger_level_configuration (app.application_config_path)
l_logs_path := l_logger_config.location
if l_logs_path = Void then
l_logs_path := app.logs_path
end
if ut.directory_path_exists (l_logs_path) then
create l_log_writer_file.make_at_location (l_logs_path.extended (app.name).appended_with_extension ("log"))
l_log_writer_file.set_max_file_size ({NATURAL_64} 1024 * 1204)
l_log_writer_file.set_max_backup_count (l_logger_config.backup_count)
l_log_writer := l_log_writer_file
else
-- Should we create the directory anyway ?
create {LOG_WRITER_NULL} l_log_writer
end
set_logger_level (l_log_writer, l_logger_config.level)
a_log.register_log_writer (l_log_writer)
end
set_logger_level (a_log_writer: LOG_WRITER; a_priority: INTEGER)
-- Setup the logger level based on `a_priority'
do
if a_priority = log_debug then
a_log_writer.enable_debug_log_level
elseif a_priority = Log_emergency then
a_log_writer.enable_emergency_log_level
elseif a_priority = Log_alert then
a_log_writer.enable_alert_log_level
elseif a_priority = Log_critical then
a_log_writer.enable_critical_log_level
elseif a_priority = Log_error then
a_log_writer.enable_error_log_level
elseif a_priority = Log_warning then
a_log_writer.enable_warning_log_level
elseif a_priority = Log_notice then
a_log_writer.enable_notice_log_level
elseif a_priority = Log_information then
a_log_writer.enable_information_log_level
else
a_log_writer.enable_unkno_log_level
end
end
new_logger_level_configuration (a_path: PATH): LOGGER_CONFIGURATION
-- Retrieve a new logger level configuration.
-- By default, level is set to `DEBUG'.
local
l_parser: JSON_PARSER
ut: FILE_UTILITIES
do
create Result
if
ut.file_path_exists (a_path) and then
attached (create {JSON_FILE_READER}).read_json_from (a_path.name) as json_file
then
create l_parser.make_with_string (json_file)
l_parser.parse_content
if
l_parser.is_valid and then
attached l_parser.parsed_json_object as jv and then
attached {JSON_OBJECT} jv.item ("logger") as l_logger
then
if attached {JSON_STRING} l_logger.item ("location") as l_location then
Result.set_location_with_string (l_location.item)
end
if attached {JSON_STRING} l_logger.item ("backup_count") as l_count then
if l_count.item.is_natural then
Result.set_backup_count (l_count.item.to_natural)
end
end
if attached {JSON_STRING} l_logger.item ("level") as l_level then
Result.set_level (l_level.item)
end
end
end
end
note
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -67,7 +67,6 @@ feature -- Output
rescue
l_retry := True
retry
end
write_emergency (msg: STRING)
@@ -135,6 +134,6 @@ feature -- Output
retry
end
note
copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -1,7 +1,7 @@
note
description: "Provides logger information"
date: "$Date: 2014-08-20 15:21:15 -0300 (mi., 20 ago. 2014) $"
revision: "$Revision: 95678 $"
date: "$Date: 2015-02-05 10:25:53 +0100 (jeu., 05 févr. 2015) $"
revision: "$Revision: 96584 $"
class
SHARED_LOGGER
@@ -9,104 +9,108 @@ class
inherit
LOG_PRIORITY_CONSTANTS
ARGUMENTS
SHARED_EXECUTION_ENVIRONMENT
feature -- Logger
log: LOGGING_FACILITY
-- New `log' (once per process)
logger: separate LOGGER
-- `log' facility (once per process)
-- that could be shared between threads
-- without reinitializing it.
local
l_log_writer: LOG_ROLLING_WRITER_FILE
l_environment: EXECUTION_ENVIRONMENT
l_path: PATH
l_logger_config: LOGGER_CONFIGURATION
do
Result := logger_cell_item (logger_cell)
end
logger_cell: separate CELL [separate LOGGER]
once ("PROCESS")
--| Initialize the logging facility
create Result.make
create l_environment
if attached separate_character_option_value ('d') as l_dir then
l_path := create {PATH}.make_from_string (l_dir)
create l_log_writer.make_at_location (l_path.extended ("..").appended ("\api.log"))
else
l_path := create {PATH}.make_current
create l_log_writer.make_at_location (l_path.extended("api.log"))
end
l_log_writer.set_max_file_size ({NATURAL_64}1024*1204)
if attached separate_character_option_value ('d') as l_dir then
l_logger_config := new_logger_level_configuration (l_path.extended("config").extended ("application_configuration.json"))
else
l_logger_config := new_logger_level_configuration (l_path.extended ("site").extended("config").extended ("application_configuration.json"))
end
l_log_writer.set_max_backup_count (l_logger_config.backup_count)
set_logger_level (l_log_writer, l_logger_config.level)
log.register_log_writer (l_log_writer)
--| Write an informational message
Result.write_information ("The application is starting up...")
create Result.put (create {separate LOGGER}.make)
end
feature {NONE} -- JSON
set_logger_level (a_log_writer: LOG_ROLLING_WRITER_FILE; a_priority: INTEGER)
-- Setup the logger level based on `a_priority'
logger_cell_item (a_cell: like logger_cell): separate LOGGER
do
if a_priority = log_debug then
a_log_writer.enable_debug_log_level
elseif a_priority = Log_emergency then
a_log_writer.enable_emergency_log_level
elseif a_priority = Log_alert then
a_log_writer.enable_alert_log_level
elseif a_priority = Log_critical then
a_log_writer.enable_critical_log_level
elseif a_priority = Log_error then
a_log_writer.enable_error_log_level
elseif a_priority = Log_warning then
a_log_writer.enable_warning_log_level
elseif a_priority = Log_notice then
a_log_writer.enable_notice_log_level
elseif a_priority = Log_information then
a_log_writer.enable_information_log_level
else
a_log_writer.enable_unkno_log_level
end
Result := a_cell.item
end
new_logger_level_configuration (a_path: PATH): LOGGER_CONFIGURATION
-- Retrieve a new logger level configuration.
-- By default, level is set to `DEBUG'.
feature -- Logging
write_debug_log (m: READABLE_STRING_8)
do
write_debug_log_to (m, logger)
end
write_information_log (m: READABLE_STRING_8)
do
write_information_log_to (m, logger)
end
write_warning_log (m: READABLE_STRING_8)
do
write_warning_log_to (m, logger)
end
write_error_log (m: READABLE_STRING_8)
do
write_error_log_to (m, logger)
end
write_critical_log (m: READABLE_STRING_8)
do
write_critical_log_to (m, logger)
end
write_alert_log (m: READABLE_STRING_8)
do
write_alert_log_to (m, logger)
end
feature {NONE} -- Logger: separate implementation
write_debug_log_to (m: READABLE_STRING_8; a_log: like logger)
do
a_log.put_debug (m)
end
write_information_log_to (m: READABLE_STRING_8; a_log: like logger)
do
a_log.put_information (m)
end
write_warning_log_to (m: READABLE_STRING_8; a_log: like logger)
do
a_log.put_warning (m)
end
write_error_log_to (m: READABLE_STRING_8; a_log: like logger)
do
a_log.put_error (m)
end
write_critical_log_to (m: READABLE_STRING_8; a_log: like logger)
do
a_log.put_critical (m)
end
write_alert_log_to (m: READABLE_STRING_8; a_log: like logger)
do
a_log.put_alert (m)
end
feature {NONE} -- Implementation
initialize_logger (app: APPLICATION_LAYOUT)
local
l_parser: JSON_PARSER
l_logger: LOGGER
do
create Result
if attached json_file_from (a_path) as json_file then
l_parser := new_json_parser (json_file)
if attached {JSON_OBJECT} l_parser.parse as jv and then l_parser.is_parsed and then
attached {JSON_OBJECT} jv.item ("logger") as l_logger and then
attached {JSON_STRING} l_logger.item ("backup_count") as l_count and then
attached {JSON_STRING} l_logger.item ("level") as l_level then
Result.set_level (l_level.item)
if l_count.item.is_natural then
Result.set_backup_count (l_count.item.to_natural)
end
end
end
create l_logger.make_with_layout (app)
set_logger_to (l_logger, logger_cell)
end
json_file_from (a_fn: PATH): detachable STRING
set_logger_to (a_logger: separate LOGGER; a_cell: like logger_cell)
do
Result := (create {JSON_FILE_READER}).read_json_from (a_fn.name.out)
a_cell.replace (a_logger)
end
new_json_parser (a_string: STRING): JSON_PARSER
do
create Result.make_parser (a_string)
end
note
copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -1,18 +1,18 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="cms_model" uuid="57C6F407-E894-4554-8A59-C8D1F3BBC5D7" library_target="cms_model">
<target name="cms_model">
<root all_classes="True"/>
<option warning="true">
<root all_classes="true"/>
<option warning="true" void_safety="all">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<setting name="console_application" value="true"/>
<library name="base" location="$ISE_LIBRARY/library/base/base-safe.ecf"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension-safe.ecf"/>
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
<cluster name="cms_model" location=".\src" recursive="true">
<cluster name="cms_model" location=".\src\" recursive="true">
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/.svn$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
</cluster>
</target>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="cms_model" uuid="57C6F407-E894-4554-8A59-C8D1F3BBC5D7" library_target="cms_model">
<target name="cms_model">
<root all_classes="true"/>
<option warning="true" void_safety="none">
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
</option>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="base_extension" location="$ISE_LIBRARY\library\base_extension\base_extension.ecf"/>
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
<cluster name="cms_model" location=".\src\" recursive="true">
<file_rule>
<exclude>/EIFGENs$</exclude>
<exclude>/CVS$</exclude>
<exclude>/.svn$</exclude>
</file_rule>
</cluster>
</target>
</system>

View File

@@ -3,8 +3,8 @@ note
CMS abstraction for CMS content entity, named "node".
]"
status: "draft"
date: "$Date$"
revision: "$Revision$"
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
revision: "$Revision: 96542 $"
class
CMS_NODE
@@ -83,8 +83,8 @@ feature -- Access
author: detachable CMS_USER
-- Author of current node.
collaborators: detachable LIST[CMS_USER]
-- Users contributed to current Node.
-- collaborators: detachable LIST[CMS_USER]
-- -- Users contributed to current Node.
feature -- status report
@@ -177,18 +177,18 @@ feature -- Element change
auther_set: author = u
end
add_collaborator (a_user: CMS_USER)
-- Add collaborator `a_user' to the collaborators list.
local
lst: like collaborators
do
lst := collaborators
if lst = Void then
create {ARRAYED_SET [CMS_USER]} lst.make (1)
collaborators := lst
end
lst.force (a_user)
end
-- add_collaborator (a_user: CMS_USER)
-- -- Add collaborator `a_user' to the collaborators list.
-- local
-- lst: like collaborators
-- do
-- lst := collaborators
-- if lst = Void then
-- create {ARRAYED_SET [CMS_USER]} lst.make (1)
-- collaborators := lst
-- end
-- lst.force (a_user)
-- end
note
copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"

View File

@@ -2,18 +2,29 @@ note
description: "[
Abstraction to represent a URI link in the CMS system.
]"
date: "$Date$"
revision: "$Revision$"
date: "$Date: 2015-02-09 22:29:56 +0100 (lun., 09 févr. 2015) $"
revision: "$Revision: 96596 $"
deferred class
CMS_LINK
inherit
REFACTORING_HELPER
undefine
is_equal
end
DEBUG_OUTPUT
undefine
is_equal
end
ITERABLE [CMS_LINK]
undefine
is_equal
end
COMPARABLE
feature -- Access
@@ -23,6 +34,21 @@ feature -- Access
location: READABLE_STRING_8
-- Associated url location.
weight: INTEGER
-- Optional weight used for order.
feature -- Comparison
is_less alias "<" (other: like Current): BOOLEAN
-- Is current object less than `other'?
do
if weight = other.weight then
Result := title < other.title
else
Result := weight < other.weight
end
end
feature -- status report
is_active: BOOLEAN
@@ -53,6 +79,16 @@ feature -- status report
deferred
end
feature -- Element change
set_weight (a_weight: INTEGER)
-- Set `weight' to `a_weight'.
do
weight := a_weight
ensure
weight_set: weight = a_weight
end
feature -- Query
parent: detachable CMS_LINK
@@ -84,9 +120,12 @@ feature -- Status report
create Result.make_from_string (title)
Result.append_string_general (" -> ")
Result.append_string_general (location)
Result.append_string_general (" [")
Result.append_integer (weight)
Result.append_string_general ("]")
end
note
copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -2,8 +2,8 @@ note
description: "[
Abstraction to represent a links container in the CMS system.
]"
date: "$Date$"
revision: "$Revision$"
date: "$Date: 2015-02-09 22:29:56 +0100 (lun., 09 févr. 2015) $"
revision: "$Revision: 96596 $"
deferred class
CMS_LINK_COMPOSITE
@@ -30,6 +30,27 @@ feature -- Element change
deferred
end
sort
-- Sort `items' and also recursively in sub items.
local
l_sorter: QUICK_SORTER [CMS_LINK]
do
create l_sorter.make (create {COMPARABLE_COMPARATOR [CMS_LINK]})
if attached items as lst then
l_sorter.sort (lst)
across
lst as ic
loop
if
attached {CMS_LINK_COMPOSITE} ic.item as l_composite and then
not l_composite.is_empty
then
l_composite.sort
end
end
end
end
feature -- status report
is_empty: BOOLEAN
@@ -47,6 +68,6 @@ feature -- status report
end
note
copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -2,8 +2,8 @@ note
description: "[
Abstraction to represent a link to a CMS resource.
]"
date: "$Date$"
revision: "$Revision$"
date: "$Date: 2015-02-09 22:29:56 +0100 (lun., 09 févr. 2015) $"
revision: "$Revision: 96596 $"
class
CMS_LOCAL_LINK
@@ -16,6 +16,8 @@ inherit
items as children,
extend as add_link,
remove as remove_link
undefine
is_equal
end
create
@@ -168,6 +170,6 @@ feature {NONE} -- Implementation
invariant
note
copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

View File

@@ -3,8 +3,8 @@ note
Abstraction to represent a MENU in the CMS system.
It has items as sub menu/link.
]"
date: "$Date$"
revision: "$Revision$"
date: "$Date: 2015-02-09 22:29:56 +0100 (lun., 09 févr. 2015) $"
revision: "$Revision: 96596 $"
class
CMS_MENU
@@ -61,6 +61,17 @@ feature -- Status report
Result := items.is_empty
end
has (lnk: CMS_LINK): BOOLEAN
do
across
items as ic
until
Result
loop
Result := ic.item.location.same_string (lnk.location)
end
end
feature -- Element change
extend (lnk: CMS_LINK)
@@ -91,6 +102,6 @@ feature -- Access
invariant
note
copyright: "2011-2014, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end

Some files were not shown because too many files have changed in this diff Show More