Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Sign In with Google Sign In with OpenID

some questions or suggestions

edited January 2012 in Future

I have some questions or suggestions here:

  1. The page editor can't change the font family? This seems useful.
  2. The layout editor can highlight code, nice. If it can change the height by user, will become better. I usually find its height is not enough.
  3. In demo, I can't form the navigation, because I can't drag item from right to left. I remembered that It could before. it seems that after modified, the left container has no item, so its area is too small to click?
  4. Can we form navigations more than one?
  5. I can modify layout files, css files, block files, and other files easily. How about handlers?



  • Thanks for the feedback! I marked the navigation drag and drop bug as an issue to be fixed, and I fixed that it wasn't resetting in the demo site as well. To answer your other points:

    1. I wanted to keep font choice out of the page editor because it can really mess up a site's design. Many designers I've worked with have asked to have that feature removed from other CMSes, so that the font families used on the site can be chosen at the stylesheet level and text will always look consistent. Then for formatting, you have header levels, emphasis, etc.

    2. Yes, this is a bit cramped. I was thinking about making a handle between the editor and preview so you can expand/contract them, or even making the preview open in a separate window or tab as another option. Not sure the best way here yet, but thinking on it still.

    3. See bug mention above :)

    4. You can only create one navigation tree, but you can use different parts of it separately in your site. For example, if you have a "products" section with sub-pages, you can show its children using {! navigation/section?section=products !} in your layout. Or if you want to show only the top-level pages, you can use {! navigation/top !}.

    5. You can't edit the PHP code from within the browser, but it is pretty easy to write handlers and upload them separately. I fear offering a full code editor would give too much power to break things...

    Thanks again for the feedback. I hope that answers your questions, and now off to figure out how to fix that bug! :)

  • edited January 2012

    Thanks, userful answer.

    For the second question, I tends to remain the two parts in a single page, make them 100% height, and give two links within a absolut float div to travel.

    I have made a chinese translation file, I wonder where to upload?

  • I like that idea, change the layout for those screens to take up 100% (I think I'll still add a control to expand/contract between the two so you can make the preview smaller or larger if you need). Will try playing with that tomorrow!

    To send a translation file, it's probably easiest to paste the file into this page:

    Then paste the link to it in here. Thanks!

  • I can't visit that link. Bad luck!

  • In that case, maybe one of these will work:

  • edited January 2012

    It's here:

    But some words doesn't change language in cms. I find that the cms admin bar is defined in apps/$appname/conf/config.php, which is organized in ini style. labels are hard coded. if I want to completely translate the whole cms, I have to modify every file.

    Why use ini file style? I‘m not familar with this. If a common php file, I will be able to use "i18n_get" function for translation.

    Some more questions or suggestions.

    1. Document for hook doesn't mention: hook list.
    2. The Navigation builder can be more powerful. Now I can build a navigation easily, but if I drag one page and drop it to left, I can't use it any more. Sometimes maybe this is not enough. for example, a blog, has a navigation on top, and also article category list in sidebar. They are different. At this time, I can't deal with it, because some pages are the same in two tree. How about after drag & drop, the page node remain in right, just have some style changes to show that it is used, then we can use it once more?
    3. Where is the solution for pagination? And also in multi language. This is useful.
    4. I very much like the feature that model and form use a shared file for validation. It is what I want,nice! The document for "Referencing other tables" seems that the example code shows a has_one relation. Can model deal with other relations like has_many or many_to_many ? It seems can't, but if I choose another library for orm, I will lose the feature...
    5. I very much like the dynamic objects. How can I add my dynamic objects myself? And if the count increase, maybe need a filter for finding the one you need.
    6. The template engine is simple and fast. I doubt that if I use a foreach section inside a foreach section, it seems to be orderless.
    7. How about write direct php code in template?


  • I used the INI format since PHP has fast INI parsing so it's easier to read and write to than a PHP script. I would have used JSON but data can potentially be seen by requesting the file directly in the browser. With the INI files, you can start with a line like this ;<?php/* and name it .php and the browser will display only a semicolon instead of the contents of the file, so it's still secure like a PHP script, but easier to edit :)

    To answer your other questions:

    1. I'm not sure what you mean. You're referring to this page right?

    2. I'll have to think on whether it's best to put a single page in multiple places in the tree, but a workaround is to create additional pages that redirect to the main one and place them in the other parts of the tree:

    3. I haven't written a good pagination solution or found the right one to include in Elefant yet. For now I've simply written a very simple one that you can see in the blog app in apps/blog/handlers/index.php where I set the count, last, more, and next values and apps/blog/views/index.html where I display the "Older posts" and "Newer posts" links.

    4. I haven't added many-to-many relationships to the Model joins yet, but I've been playing with some ideas for it. I want to make sure it works very naturally but also creates efficient SQL behind-the-scenes.

    5. There's some info on creating your own dynamic objects at the bottom of this page:

    6. I'm not sure what you mean about foreach and sorting. I usually sort the data in PHP before sending it to the template myself :)

    7. Yes, you can put direct PHP into the template instead of the tags. You can refer to the data passed to the template like this: <?php echo $data->title; ?>

  • edited January 2012

    I'm sorry, my english is poor...

    The first question is: there are some build-in hooks, right? Show them in a list or table may be useful.

    The sixth is like this:(in template)

    {% foreach pages %}
    {{ loop_index }} - {{ loop_value }}
    {% end %}

    It works well. But

    {% foreach pages %}
    {% foreach loop_value %} //foreach again
    //I think I will be confused
    {% end %}
    {% end %}

    Thanks to your wonderful document!

  • edited January 2012

    That's a good idea to have a list of built-in hooks. I've added it to the hooks page now:

    For multi-level loops in templates, here's an example of how it works:

    In apps/test/handlers/test.php I created this:

    $data = array (
        'my_list' => array (
            array ('One', 'Two', 'Three'),
            array ('Four', 'Five', 'Six')
    echo $tpl->render ('test/test', $data);

    Then in apps/test/views/test.html I loop through {% foreach my_list %} in a <ul> then loop through the {% foreach loop_value %} in each:

    {% foreach my_list %}
        <li><strong>{{ loop_index }}:</strong><br />
            {% foreach loop_value %}
                {{ loop_index }}. {{ loop_value }}<br />
            {% end %}
    {% end %}

    The output looks like this:

    * 0:
        0. One
        1. Two
        2. Three
    * 1:
        0. Four
        1. Five
        2. Six
  • edited January 2012


    I found that in desigher page, when listing layout and css files, each link is linked to the direct file. I usually want to go to the edit page. Change this may be more helpful.

    In user and controller class, there are some require_* functions. In user class, the function checks the authenticate staus. Renaming it is_* maybe easier to understand. It means:

    if (! User::require_admin ())

    change it to

    if (! User::is_admin ())

    Is it better?

    On the other hand, the user class has require_admin function. How about add a require($type) function, to check more group types, not only for admin, or member? And maybe a user has more than one role, $type may be an array.

    A optimizing suggestion: autoload searches classes when need a class. How about caching the file path information?

    It seems that adding two hooks is useful: before_handle, after_handle. As elefantcms use handle rather than controller class( it seems controller in elefantcms is similar with route in others), we can't extends a parent class to share code. These hooks may be useful.

  • I cleaned up the User model today and I think it's much better now. I got rid of the lazy global object I was using before, wrote some unit tests for it, and added a few new methods:

    if (User::is ('member')) {
        // User type is member
    // Get a value
    echo User::val ('name');
    // Set a value
    User::val ('name', 'New name');
    // Save the info
    User::save ();

    That should make it easier to check new types, and to get/update user info cleanly. I kept the User::require_admin() naming for now, but for most uses using $this->require_admin(); is probably better anyway (from

    Thinking about the before_handle and after_handle hooks, I'm not sure if adding them is the best way. The bootstrap.php file (see may be adequate to solving the before_handle hook at least. I'll have to think more on that.

    And for the designer links, that gets me too sometimes. I meant it as a preview link but it doesn't work well for that. I will see if I can improve on that. Thanks! :)

  • edited January 2012

    I like it:)

  • edited January 2012

    User class can save serialized data in a extra field, so it can be extended to more dynamic fields as you like. it's nice. Other models also need this feature?

    For example, usually the post model is designed enough. But in some themes( as some wordpress themes) it perhaps needs an additional field to save a special picture for each post.

    Perhaps we should let the model class also has the ability like use class. Of course, doing this we will have to add every table a extra field. But it will be more extensible, right?

    Or not every model needs this feature, because dynamic data can't be found by database. So have a normal model class for normal use(it has now), then a advModel for extensible use, this may be better.

    I also have a question, if data is from the extra field, using the INI-styled form file seems to will have a problem, as we get data using:




    These days I am away from my home, so I can't test it. But I think it may be.

    If change the model class, we can get data form the same implement:


    we don't need to care about where the data from. This may be more simple and less problems.

    Another suggestion is, elefantcms doesn't support muliti site installed in a database. After subfolder installation support, this can be done.

    Thanks to your efficient work. I wish elefantcms becomes more and more excellent.

  • Great idea to make that more general. Check out the ExtendedModel class I just checked into Github. I'm thinking of extending the blog post model with it like this:

    namespace blog;
    class Post extends \ExtendedModel {
        public $_extended_field = 'extra';

    Then you'll be able to add fields to a blog post like this:

    $post = new Post ($post_id);
    $extra = $post->extra;
    $extra['photo'] = '/path/to/image.jpg';
    $post->extra = $extra;
    $post->put ();

    Unfortunately, you can't just do a $post->extra['photo'] = '/path/tp/image.jpg' in PHP because accessing the member of the array causes it to not trigger the __set() method. That's why the $extra = $post->extra and $post->extra = $extra lines are needed...

    I wonder if I could also add a special getter/setter method to ExtendedModel to simplify this further, something like:

    // set an extra field
    $post->extended ('photo', '/path/to/image.jpg');

    Then you could also say:

    // get a single field
    $photo = $post->extended ('photo');

    And even:

    // return the whole array
    $extras = $post->extended ();

    That would be easy to add. What do you think?

  • I've added an extra property to blog posts now, and added an ext() method to ExtendedModel for accessing extra values like in my last post.

    Next I'll also need to figure out how to add custom-defined properties to the post add/edit forms too. Maybe as a configuration option in the blog app. Hmm... :)

  • edited January 2012

    I make a try here: .

    I'm poor in php, and now I have no develop environment, so I didn't test the scirpt, and even there may be syntax errors. But I think it shows my idea.

    Main idea:
    1. use __get() and __set() to have the same implement as normal field;
    2. give a default extra field name;
    3. extra field named 'extra' may be too normal, because it may has been used.
    4. I'm not sure that we need to append new extra data field by code. For example,


    will work well when the model has the pic extra data field, but if it hasn't, ignore it or add a new field and value?
    5. further feature: define the form information (see TODO in code). So we would be able to just define this array, then build the custem fields in form. It's nice, isn't it?

    I didn't develop anything before, but I like thinking :)

  • I'd like to figure out a way to include validation for the extended fields in the regular model validation, maybe with an 'extended' flag value, for example:

    [title] /* regular field */
    not empty = 1
    [photo] /* extended field */
    extended = 1
    regex = "/.*\.(jpe?g|png|gif)$/"

    This way it would simply know to use the $_extended_field instead of trying to get/set it directly, causing the SQL to fail too.

    This could also allow it to build a list of extended fields so the ordinary __get/__set would know to pass it on as well, since otherwise it wouldn't know to do so. That could be a workaround for the fact that you can't say $model->extra['photo'] because PHP won't trigger __set() on the $model when its inside the array.

    I'm going to file an issue for this and think more about it for now.

  • Good!

    How about my idea above? If that is feasible, it seems simpler and better.

  • I just added the validation for extended properties, but I also modified the __get/__set methods so that if an extended property is defined in the $verify list, you can then access it directly via $model->extended_field_name, for example:

    $blog_post->photo = 'example.jpg';

    I believe that's what you meant, right? It definitely makes it simpler, although it adds a bit of "magic" to how those properties work, but not too much I think :)

  • aha, I like it!

  • edited January 2012

    Admin toolbar seems to miss a link to edit current page.

  • The edit buttons should appear inside the page next to the content that's editable. I wanted to keep the toolbar as clean and simple as possible, and since you can also edit blocks as well, I think this makes it clearer what content you will be editing when you click an edit button.

  • oh, sorry, I'm too careless.

  • edited February 2012

    I want to optimize the performance of elefantcms even faster, so I have a try to add file path cache for autoloader.
    Codes are here:
    Unluckily, it doesn't work. I don't know what's wrong.
    These days my wife is sick in hospital, so I don't have time to fix it.

    Another suggestion, elefantcms globs config files and combines the values. In this way, apps can easily extend the system. Then, I think it is valueable to wrap it as a function for further use.
    For example, function glob_config($section, $handle,$file='config.php').
    Then, when we want to analyse a config section in all apps, like "mySection", just use code:

    //other codes
    function dosomething(){
  • edited February 2012

    Your class map suggestion got me experimenting over the last couple days. I just posted results here:

    In the end, it looks like the class map ended up taking more memory and I couldn't get it to improve performance by any real amount.

    For the configurations, I'm not sure what you mean beyond the config info at these pages:

    The global configurations are always available, and an app's configurations are automatically loaded within the app itself. You can also in theory access the configurations from other apps as well via:

    echo $this->appconf['blog']['Blog']['title'];

    But you would need to ensure the blog app was loaded already. Do you mean that you want to be able to load their configurations manually if they haven't been called yet?

Sign In or Register to comment.