Layout Design

Asked by mallow on 2007-06-08

Are these the files that will enable me to change the site's frontend look, as in changing color, adding a background image, changing the header at the top??

Is there any document for layoutdesign besides this one: to help understand how silva is structured, I know HTML and CSS but the above files look greek to me.

Question information

English Edit question
Silva Edit question
No assignee Edit question
Solved by:
Jasper Op de Coul
Last query:
Last reply:

This question was reopened

mallow (princemallow) said : #1

I put the following in a folder inside of a silva publication under the title overide.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">
<!-- Silva 2.0 -->
<!--html metal:use-macro="here/layout_macro.html/macros/layout"-->

When I access a page within that folder under public view, Shouldn't I see nothing? I see the page as I normally would otherwise?

Kit Blake (kitblake) said : #2

Yes, you should see nothing. If you a <p>Hello world</p> between the body tags then you should see Hello world.

To answer which files change the site's frontend look, you can edit:

These files can be changed later once the look is defined:

Note that these files are what we call the "ZODB-based" layout. If you have a product called SilvaLayout installed, changes in the ZODB won't have any effect. All the skinning files are on the file system. For you learning curve it's better to work the ZODB-based layout.

Kit Blake (kitblake) said : #3

Plus, this document is the most informative there is. If you know html and css, just ignore anything that you don't understand. However, if you want to do anything more than change a logo or colors, you must learn some TAL (Template Application Language, see the Zope book on

mallow (princemallow) said : #4

Interesting because I do see something with that code, I think I do have the layouts installed and I'm wondering if it installed on it's own. So given that layouts are installed that means that overide.html won't work?

I am familiar with HTML and CSS, and I did a quick and small Tal tutorial before posting. Which is why I'm confused that I'm seeing content.

So now comes a two part question, How do overide work with silva layout?
Would you recommend that I uninstall silvalayouts for now?

Kit Blake (kitblake) said : #5

Yes, uninstall (meaning remove) the SilvaLayout product from the Products directory of your Zope. Then the override will work. The override.html file defines the public view for the container (folder/publication) that it's in. It only affects the container, not the other docs. Normally it's used for a home page or a sub-home page.

mallow (princemallow) said : #6

I'm sorry to bring this up again but I just realized that I did not put the silva layout inside of my products page for this instance?? So i'm baffled?

mallow (princemallow) said : #7

Never Mind, I mistakenly put overide instead of override, that is why I was getting problems; I'll continue to ask questions here about layout when they arise.

mallow (princemallow) said : #8

Is there a wysiwyg program that can handle all these files and allow the designer to see the page rendered?

mallow (princemallow) said : #9

Why is there a frontend.css in silva root and in the global folder, is the one in global the one called until the attribute is replaced in the one in the root?

Kit Blake (kitblake) said : #10

No there is no wywiwyg program that understands TAL. It's best to just reload in your browser, since that will be the viewer your users use.

Your other query (actually a new one question) about the css. Yes, the frontend.css in the root imports the frontend.css in globals. This means you can change, or override, any of the selectors.

mallow (princemallow) said : #11

Alright, I've had a few hours inside of Silva, and it's getting better and better...

I'm currently looking through http://localhost:8080/Soleil/docs/manager/Public_API_Silva and i'm having difficulty getting some of those to work.... In short let me describe to you what I'm seeking to do. First I'll draw a map of how we set up out publications (If after posting it skews over I'll repost an image...)

                            Publication Vol. 1 (A) Publication Vol.2 (G)
                             / \ / \
                  folder(B) folder(E) folder(H) folder(J)
                  / \ \ | / \
        Article(C) Article (D) Article (F) Article(I) Article (K) Article (L)

Both Publications represent one newspaper printed on paper, thus two newspapers are present above
The folders are identical in name and ID and represent sections of the paper
The only difference between the sections lie in there being some sections that are not always published
And obviously the number of articles in each section changes
So for this purpose folder B and folder H are the same section and like wise for E and J
How would I go about making a navigation bar that displays each "Section" and once clicked all the articles of the sections for example
Nav bar
Section 1 = (Title of Folder B and H)
Section 2 = (Title of Folder E and J)

and within each of these section say section one
I get a display of choices between Article C D and I

mallow (princemallow) said : #12

I'm sorry it skewed give me a minute to make an image to upload

Kit Blake (kitblake) said : #14

As in your diagram, for each newspaper you have a publication (as
opposed to a folder). You can use get_publication to define the top of
your newspaper navigation.

When a visitor enters the newspaper/publication, use get_container to
get all the folders and create a nav bar with all the sections showing.
Then, when a user clicks/enters a folder, use get_public_tree to get the

See the "cascading table of contents with location" navigation code in
your: http://localhost:8080/Soleil/docs/layout_macro.html/manage_main

mallow (princemallow) said : #15

Ok... is there a way to list all the articles in all publication?

mallow (princemallow) said : #16

I mean, a list of all articles in the database, with purhaps capability of excluding some

mallow (princemallow) said : #17

and I might as well address this now.... If I have folders without an index or a TOC then the folder displays nothing; What can I do with this?

mallow (princemallow) said : #18

<div class="toc"
    publication here/get_publication;
    currently_at_publication python: ==;
    locator here/location.png/absolute_url | nothing;
I think this is what I want to change... It will list the current publication, I want to get the tree of all the publications, and merge the foldernames, thus I'm thinking perhaps somehow call a tree for one publication, and then switch to another, skip the folder, and list the articles, and then do that for each iteration... but I don't know what modules there are besides currently_at_publication? (if that is a module, that is?

mallow (princemallow) said : #19

whoops realized that is just the bullet...

mallow (princemallow) said : #20

rather ignore the above code
<a tal:content="publication/get_title_or_id"
    href string:${publication/absolute_url};
    class python: currently_at_publication and 'location' or nothing;
  Silva Documentation
<tal:def define="tree publication/get_public_tree">
<tal:if condition="tree"
  repeat="obj tree">
<tal:def define="
  indent python: obj[0];
  item python: obj[1];
  title item/get_short_title;
  currently_at_item python: ==;
If I can do that for one publication, and where it repeats go off to the other publications too, skip over obj[0] (since it's already there; all folders are the same) and continue with printing obj [1].... well essentially what I'm looking for is just a list of the folder, that would link to all the articles which are in other folders....??? Don't know if you understand

mallow (princemallow) said : #21

Ok I'm getting closer to what I'm looking for, however for some reason I cannot put anything in the () below, I always get an error whenever I try to put a number in get_public_tree(depth), how is this implemented?
<tal:block tal:repeat="pair here/get_public_tree_all(-1)">
  <!-- increase padding-left by 16px according to depth in tree -->
    tal:define="indent python:pair[0]"
    style python:'padding-left: '+str(indent * 16)+'px';
    <a tal:define="item python:pair[1]"
       tal:attributes="href item/absolute_url"

Kit Blake (kitblake) said : #22

Arguments cannot be used in path expressions, you must change the repeat to Python:

<tal:block repeat="pair python:here.get_public_tree_all(-1)">


mallow (princemallow) said : #23

Yes finally got it, unfortunatly no matter what number I put it doesn't change.... however I decided to work on the "_______ cascading table of contents with location _______ " part as a trial an error thing...

I was trying to figure this out on my own, and I finally realized with the statement == that whenever the tal says here, it refers to "here in this document" as oppsed to "put content here in this tag" correct me if I'm wrong please....

so is there a way to make the

publication here/get_publication;
go up or down one folder??

Kit Blake (kitblake) said : #24

Yes, 'here' is the object that you're in. It's the same as 'context' in Python. The statement == is checking to see if the current document/object is the same as the one being rendered in the repeat loop.


publication here/aq_parent/get_publication;

The aq_parent (acquire parent) will make it go up a level. If the next level up is not a publication, but a folder, it will continue to go up until it finds a publication (which may be the root).

mallow (princemallow) said : #25

Ok thanks, it worked but I'm beginning to understand Tal a little better, and I don't think that is the best way to go

This bit of code is within the TOC of the layout macro
tal:def define="tree python:publication.get_public_tree_all(0)">
  <tal:if condition="tree"
   repeat="obj tree">
      <tal:def define="
        indent python: obj[0];
        item python: obj[1];
        title item/get_short_title;
        currently_at_item python: ==;
        is_container python:obj[1].implements_container;
I added the last line....
Now I just want to make sure that I assume correctly that, obj[0] gets the length of the string for each object in the tree
and that obj[1] is the value of the string of the object in the tree

I can use the is_container to make an if condition for a particular line of code to run
And I can similarly do an is_content for articles within silva, however how would I go about doing the following

If object is a content, then find the container that this content belongs too

because along the line I will want to do this:
content_belongs_to_current_container python: ==

So I need to know hot to make the that checks for the content's container

Does that make sense

[ Have I come a long way? :) ]

mallow (princemallow) said : #26

I just tried this:
<p tal:content= "python: item.aq_parent.get_title"></p>

but I get this:
<bound method Folder.get_title of <Silva Folder instance Actualites>>

If I could get red of everything but the Actualites then all I have to do is figure out how to restart the loop

mallow (princemallow) said : #27


Defined: owned_title item/aq_parent/get_short_title;
and content owned_title and bingo I got what I wanted... I'll probably get questions later

mallow (princemallow) said : #28

And I'm back...

<tal:if condition = "item_is_container">
<tal:def define="global container_store python: title "></tal:def>

<tal:if condition = "item_is_content">
<tal:if condition = "published">
<p tal:content="container_store"></p>
<p tal:content= "owned_title"></p>
Error Value: name 'container_store' is not defined

If I declare it as a global variable should it not be available outside of the if statement?

mallow (princemallow) said : #29

Testing for a condition to create a variable left me with an undeclared variable on the first run through, thus I needed to define the variable with dummy data outside of the initial loop in order to work.

mallow (princemallow) said : #30

Is there a way to use tal to count the number of publications; I was thinking something along these lines

<tal:def define="
     indent python: obj[0];
     item python: obj[1];
     item_is_publication python:item.implements_publication;

<tal:if item_is_publication>

<tal:define = "first_publication item/get_short_title;">

However I'm not sure how to create a new variable without creating a bunch before hand , but I rather make this self-efficient only creating the variables it needs


mallow (princemallow) said : #31

Using this, it works excepts it gets unpublished publications too, but I don't suspect any problems

<tal:def define="global count_publication python:0;"></tal:def>
    <tal:if condition="tree" repeat="obj tree">
              <tal:def define="
   indent python: obj[0];
   item python: obj[1];
   title item/get_short_title;
   currently_at_item python: ==;
   item_is_publication python:obj[1].implements_publication;
     <tal:if condition = "item_is_publication">
       <tal:def define="global count_publication python:count_publication+1"></tal:def>

Any suggestions to refine this code is welcome

mallow (princemallow) said : #32

well alright let me update this to date:

As I stated earlier currently the site is under this format

Volumn 1: (Publication folder)
  Editorial (folder)
  Local News (folder)
Volumn 2: (Publication folder)
  Editorial (folder)
  Local News (folder)

and I managed to get it to display this
Editorial (4 being the most recent)

  Local News (folder)
However I'm doing that by running the tree into a loop (as it is in the table of contents) and then it compares each container, on the first run it says if container is equal to editorial then print editorial once and then it goes through all the items and says if you are a content and your parent is (whatever container is currently stored) then print that article so on and so forth

I can already see a potential problem in the future, being that it has to go through all the items in the tree, once the paper gets going, (weekly is coming soon for the season) it will become slow and bogged down...

I don't think silva was built for the purpose above specifically, I'm sure it's possible but with lots of work... Is there an alternative instead of going through a tree? Is this reasonable? (We can always change the format of our data and just forget about doing it by publication and instead store it like the second output.) However I'm wondering if you guys know of anything beforehand?

mallow (princemallow) said : #33

alright here is the code I made for the above to work, is there a way that you can see really quickly to avoid having to go through the loop 32 times?

Ah I see, that is a bit strange,
why not put all your strings in a list and loop through that, instead of using range(), so:

<div tal:repeat="container_store python:['Actualités Floride', 'Éditorial', 'Article']">

etc, etc,.

Also, I'm not sure why you use global variables everywhere, you should not do that, it is very confusing. If you look at the Silva templates, you will probably never see any use of global variables.

Ah I see, that is a bit strange,
why not put all your strings in a list and loop through that, instead of
using range(), so:

<div tal:repeat="container_store python:['Actualités Floride',
'Éditorial', 'Article']">

etc, etc,.

Also, I'm not sure why you use global variables everywhere, you should
not do that, it is very confusing. If you look at the Silva templates,
you will probably never see any use of global variables.

mallow wrote:
> Question #7883 on Silva changed:
> mallow gave more information on the question:
> alright here is the code I made for the above to work, is there a way
> that you can see really quickly to avoid having to go through the loop
> 32 times?

mallow (princemallow) said : #36

That is really good news, I was trying to figure out how to make an array with tal (since I have no way of knowing how many articles there will be in advance) but I couldn't make it work out, and with looping that way, I only found how to do it with numbers on the web... But that's perfect, it is exactly what I needed.

that line now looks like this
 (one variable to make it easier to test and make sure it works)

However I still need go through the tree, so I would need a repeat obj tree somewhere it seems to work fine with this

<tal:if condition="tree" repeat=" container_store python:[ 'Article', 'Sous les Palmiers', 'SPORTS et loisirs' ] "> (just a few variable to make it easier to test and make sure it works)
<tal:if condition="tree" repeat=" obj tree"> (I have to iterate all the objects too so that the title changes, is this correct

now only one problem occurs. Accent marks in the container store area such as 'Actualités Floride' give me an error:

System problem
  Something went wrong. Please use your back button to return to the previous page. Sorry for the irritation.
    Error Type: UnicodeDecodeError
    Error Value: 'ascii' codec can't decode byte 0xc3 in position 8: ordinal not in range(128)
    Error info
    Path: /Soleil/
    URL: http://localhost:8080/Soleil/
       more details....
      Browser: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv: Gecko/20070515 Firefox/
      Remote address:
      Remote identity:

Is there a way to escape this character because
'Actualit&#233;s Floride' does not really equal the title 'Actualités Floride'

mallow (princemallow) said : #37

Ok... I can store the strings in varibles and then do that same thing except with variables instead of strings, thanks Jasper Op de Coul, I'm modifying the code now, i'll post some results...

mallow (princemallow) said : #38

Thanks Jasper Op de Coul, that solved my question.