Please create an account to participate in the Slashdot moderation system

 



Forgot your password?
typodupeerror
×
Books Media Programming Book Reviews IT Technology

Two Books On Plone 107

Robert Nagle writes "Over the last year, Zope and Plone have gained mindshare as open source web application servers. In the last few months, two books have come out about how to use, extend and administer Plone. One is Andy McKay's Definitive Guide to Plone (available for free online), and the other is Julie Meloni's Plone Content Management Essentials." Read on for Nagle's review of both books.
(See each)
author (See each)
pages (See each)
publisher (See each)
rating (See each)
reviewer Robert Nagle
ISBN (See each)
summary McKay's book is indeed definitive; Meloni's book is a good introduction

The Zope/plone combination offers a variety of advantages to the open source developer: robust workflow capabilities, conformity to Web standards, cross-platform support and a sophisticated security model. On the other hand, it has a steep learning curve and deals with objects in an object database (instead of the usual RDBMS/LAMP data model).

First, here's 30 seconds of what Plone is all about (the Slashdot editors can provide the bunnies). Zope is a Python-backed web application server which includes a Zope Management Interface (or ZMI), a web-based interface to modify templates and interact with/administer the Zope Object Database (ZODB). Although Zope can be a standalone webserver, in fact people usually put it behind Apache for reasons of security, performance and caching. Years ago, Zope used a custom scripting language (DTML) to do its business logic, but later switched to an XML-based templating language called ZPT and let users use Python-based scripts to perform actions. Zope is the application server; CMF is the content management framework, and Plone is the standards-compliant front end that lets you manage skins, slots, styles, portlets, forms, actions, content types and installation of products. Then there's archetypes, which make it easier to create new content types and web forms. Oh, have I mentioned that we're dealing with objects here? In other words, we're not just throwing data and text into SQL); we're creating different types of content (documents, events, multimedia objects), storing them as objects (with actions, metadata, etc) and then summoning them (or parts of them) from the object database with ZPT using macros and indices.

From a design perspective, Plone is elegant although so multi-layered that it's often hard to figure out where to make changes. Also, while the Plone front end is snazzy, most users end up having to go to the ZMI to modify the template and edit actions (which, depending on how you look at it, can be an advantage or disadvantage). Finally, although the list of open source products for Plone and Zope is impressive, they don't necessarily play well together, and many products for Zope don't work in Plone and vice versa.

Definitive Guide to Plone
author Andy McKay
pages 584
publisher Apress
rating 5
ISBN 1590593294

That is where Andy McKay's book and Julie Meloni's book come in. Of the two books, Andy's is more comprehensive and geared toward the experienced developer (and typical Slashdot reader); Julie's book does more hand-holding and provides more thorough explanations of introductory concepts.

As a lead plone developer, McKay has intimate knowledge of the good, the bad and the ugly for plone. Although his chapters fly by certain introductory tasks at record speed, he explains things well and offers lots of tips and hints throughout the book. (I can't tell you how many times I've put the book down and exclaimed, 'Aha, so that's how you ...'). The sequence of presentation is generally logical with one exception: in chapter 14 (page 459), the book mentions that you can use Zope Enterprise Objects to debug a live server without having to shut down Plone. That is valuable -- even vital-- information, and belonged in the earlier chapter on installing Zope. Although the chapters don't go into great depth, his code examples and commentary are sufficient to explain what is going on.

It's not the main focus of the book, but the sections on system administration (caching, tuning, scaling) are well done although some things are missing (like Virtual Host Monster). It's assumed that readers will be able to find this information elsewhere.

The best parts about McKay's book are how it relates Python programming to Plone. The deeper you get into Plone, the more important it is to write Python scripts and do basic Python debugging. Even basic sysadmin tasks like product management seems to require an understanding of object-oriented concepts. One initial difficulty comes with the idea of URL paths corresponding not to actual directories but objects being contained within other objects. (So that login_form in http://foobar/login_form doesn't necessarily reside within the foobar directory, but is in any directory or object acquired by the foobar object). This type of URL (called a traversal) is explained well enough in the book, but often makes it difficult to figure out where to find things within the ZMI and the file system. Who would have ever thought that the place to edit the login_form object for http://foobar/login_form is /foobar/portal_skins/plone_forms/login_form within the ZMI (which is actually /zopeinstance/products/CMFPlone/skins/plone_forms/ login_form.pt on the file system)? That's why McKay's skin example (in Chapter 7) accomplishes so many things; it provides a "guided tour" through the layers (i.e., scripts, templates, etc) contained within portal_skins; it also runs through the process of creating custom templates and forms based on existing ones. This, by the way, is one of the niftiest features of Zope/Plone; you push a Customize button in the ZMI, and voila! you've cloned an object for customizing. This is dense stuff, but after reading this chapter, I have a better sense of the beast I'm dealing with.

I particularly liked the book's chapters on archetypes and manipulating content types. If Zope/Plone is about manipulating objects, then it helps to have a variety of objects to manipulate. Archetypes lets you create new content types and new views for content types. By providing Python libraries for fields and widgets, archetypes makes it relatively easy to create web forms for data input. McKay's book covers this topic thoroughly and clearly. I also appreciated the chapter on searches and indexing (and the helpful table of indices and index types); this filled in a lot of gaps in my knowledge. The sections on security and workflow contained good examples, and the book also contained a section on internationalization. The programming chapters are the best parts about the book.

On the negative side, I wish there were more charts and tables in the book (perhaps as appendices). A lot of this is already found within Zope help or the Plone site, but it would have been handy to have these things as reference. Although McKay's book contains a good (though brief) introduction to Zope Page Templates, the explanation of the syntax is scattered throughout the ZPT chapter; it would have been much better to summarize all the tal tags in a single table.

Also, at many points during the ZPT chapter and other chapters, McKay refers to Plone and archetype API classes that are described nowhere else in the book. It took me a while to figure out where these things were coming from (and I would refer you to here for API descriptions). The book would have benefited from a better description of APIs, even a high level view of it (You can find some quick references here).

Because of its focus on development, McKay's book spends almost no time on third-party products or "sanctioned" products available in the plone collective. This is somewhat understandable (given the mercurial nature of product development), but the casual reader might finish the book without realizing that additional additional products even exist. (Here's a fairly comprehensive list of Plone and Zope products).

Also, I would have liked better explanation about change management. Plone has its own product installer, but I always have difficulties upgrading products. How do you test products before actually deploying them? How do you manage upgrades (and how do you upgrade Zope itself?) For such an extensible project as Plone, managing the installation, testing and upgrade of third-party products can be a disaster waiting to happen.

Plone Content Management Essentials
author Julie C. Meloni
pages 258
publisher SAMS
rating 3
ISBN 0672326876

Julie Meloni's book takes a different approach to the subject, one geared less to Python development and more to deploying third-party products and customizing site appearances. I'm tempted to say that the typical Slashdot reader would find this book "shallow," but really that is not fair. Although Meloni's book contains a short appendix on Python, it focuses more on how Plone works out of the box and how to take advantage of core functionality. In fact, Meloni's slender book contains many useful sections probably deemed too elementary for McKay's book: how structured text works, for example.

Rather than trying to cover everything Plone-related, Meloni identifies a small number of typical tasks and explains them in detail. For example, the book documents the Plone style sheets and how to modify them in the ZMI. Too basic, you say? Well, yes, but it's still useful reference material. Rather than trying to teach you how to write your own Plone product or content type from scratch, she walks us through using that nifty Customize button to clone existing templates for customization (although to tell the truth, you still need would need to know a good bit about Python and ZPT syntax to complete the task). Although the book's section on skins focused mainly on how they relate to style sheets, I found the section on customizing slots to be particularly useful.

In contrast to McKay's book, Meloni spends a separate chapter on deploying and using several popular plone products: a discussion board, a weblog and a photo album. Given that several competing products exist for each category, and that better products are likely to come out later, this chapter will probably be the first to go out of date.

Perhaps the book could have spent less time on the products themselves and more on managing products and testing/troubleshooting them.

Of the two books, McKay's book is the more indispensable, even though I still wound up consulting external sources fairly often for clarification. On the other hand, after reading first McKay's book and then Meloni's, I wish I had read Meloni's book first. Meloni's book provides a great introduction to basic plone concepts; McKay's book is great for the power user/developer. (Still another book, recently released, Cameron Cooper's Building Websites with Plone probably goes into more detail on the Python side; read a sample PDF chapter).

Perhaps I sound like a shill for the publishing industry when I say this, but it sometimes make sense to possess two or more books on a topic. The decision-making process for geeks buying books can sometimes differ radically from the general public. Geeks, for example, don't have qualms about paying full price for a new book if the content is up-to-late and relevant to the task at hand. The ordinary reader might make a purchasing decision on the basis of which book constitutes the highest information density (the $20 book with 200 pages vs. the $30 books with 500 pages). Geeks are also more inclined to view the purchasing decision in terms of time saved (i.e., how much time will reading this book save me in the long run?) From the standpoint of saving time, there's a lot to be said for reading an introductory book first and then moving to a book on more advanced topics.

Of course, Andy McKay's book is available already for free on the web (and kudos to Apress Publishing for allowing this).

** Actually, mysql/postgresql DB adaptors make it possible for Zope to fetch/send sql data; and Archetypes has a function, SQLStorage, to allow data from content objects to persist in a sql database (news to me).

Other Web Resources:


Robert Nagle (aka idiotprogrammer) writes fiction under various pseudonyms. He lives and works in Houston, Texas. In early 2005 he will be launching a plone-backed literary community ezine. You can purchase the Definitive Guide to Plone from bn.com; bn also carries Plone Content Management Essentials . Slashdot welcomes readers' book reviews -- to see your own review here, carefully read the book review guidelines, then visit the submission page.

This discussion has been archived. No new comments can be posted.

Two Books On Plone

Comments Filter:
  • Plone is great (Score:2, Insightful)

    Its the most comprehensive CMS out there...
    • Re:Plone is great (Score:3, Interesting)

      Have you actually tried to develop new content types (Filesystem Products) for it? Plone stand-alone (plus any premade products) is/are great. Developing your own stuff is a god damned nightmare. That's what I'm doing as of now, that is my job.

      Plone is based off the Zope CMF, documentation for the CMF/Plone (from a developer standpoint) is virtually non-existent.

      I'm only persisting because I know once I figure it out one time, I'll have a good scaffolding for any future content types. I've spent over 2 we
      • Re:Plone is great (Score:4, Informative)

        by polin8 ( 170866 ) on Tuesday December 21, 2004 @06:53PM (#11154087) Homepage

        Developing with CMF was pretty crappy, developing for Plone with Archetypes [sourceforge.net] is a huge improvement. Python and TAL, may not be perfect, but they provide a very simple platform for rapid web based application development.

        Your right about docs, they've been questionable in the past. The new plone.org docs section is a big step in the right direction.

        • Archetypes is much prettier to work with, but a lot of the stuff it eliminates is just boilerplate anyway. I found only one example of using multiple permissions in Archetypes and it was overly complex and convoluted (better than nothing?). Doing this in Zope (and CMF?) is as simple as one function call.

          Archetypes docs are also kinda crappy, I have references out the yang. However what I do not have, are good working examples of simple to complex products; with detailed explanations of what's happening. I
        • Even developing with Plone and Archetypes is pretty crappy compared to any real environment I've ever used. We wasted tens of thousands of euros on this crap before understanding that the transactional support is totally broken and the Oracle modules leak memory like nothing I've ever seen.
  • Soap on Zope. (Score:3, Interesting)

    by killjoe ( 766577 ) on Tuesday December 21, 2004 @06:03PM (#11153649)
    Has anybody figured out how you can publish your python methods as soap calls? It does XML-RPC but where is soap?
    • http://zope.org/Members/EIONET/SOAPMethod/

      may be what you're looking for. Not ideal, but it will let you serve SOAP from Zope
      • According to the description that's a SOAP client not a server.

        In other words it lets you call soap servers from inside of Zope. I need to go the other way.
    • A related question - has anyone actually figured out a way to do something useful with SOAP, where the benefits outweigh the gigantic PITA of developing and debugging with SOAP? Oh, and with acceptable performance?
      • Not with SOAP, but I have been able to do some useful things with ZOPE and XML-RPC. If you view Zope as essentially a large graph of persistent objects, the URLs of wind up corresponding to a method of a running application. Any request made as a standard HTTP request, spits up the return value of the method. (as perhaps modified by python's str() when it sends it out the stream back to the client.) For Zope's XML-RPC support, it will just automatically marshall the Python return value into an XML-RPC strin
        • I've done a few fun things with XML-RPC myself, especially came in handy for getting Perl and Java to talk to each other. I was just wondering what SOAP offers over and above XML-RPC that justifies its awesome bloat.
          • Basically two things.

            1) Soap and provide an RPC mechanism for complex objects not just simple values like strings and numbers. For example if you had a method that returned an object the SOAP client would provide a stub for that object for you automatically.

            2) The proper propagation of exceptions back to the client.

            There is also the fact that SOAP is theoretically transport independent. In other words you ought to be able to call soap objects via SMTP for example.

            Most soap implementation fall far short
          • I'm sorry, I thought you meant meant the bloat of SOAP over other RPC mechanisms (ONC-RPC, DCE, Java RMI, or even COM and CORBA) and were complaining about constant XML parsing and conversion from UTF-8 to internal data type representation. The complexity of SOAP over XML-RPC is obvious from specs. For an equivalent RPC call I'm not entirely sure that I'd believe that there is much of a difference in the payload size or in the time spent marshalling/unmarshelling the data. Of course with all the extra featu

    • Re:Soap on Zope. (Score:3, Informative)

      by alangmead ( 109702 )

      Zope doesn't come with SOAP support as standard. There is some work (like the SOAPByCIGNEX [zope.org] module) being done to allow it to be available as an add-on.

      There was a recent discussion [zope.org] about it on the Zope-dev mailing list.

  • by Coward Anonymous ( 110649 ) on Tuesday December 21, 2004 @06:13PM (#11153725)
    Just today eWeek published their Enterprise Apps Top Products of 2004. At #6 is Plone [eweek.com]
  • by Sweetshark ( 696449 ) on Tuesday December 21, 2004 @06:21PM (#11153788)
    Does someone have expierence using a lightweight webserver like thttpd, tux, boa, lighttpd in front of zope/plone instead of apache? Is there some equvialent of VirtualHostingMonster for one of those? I mean, apache is a but of a bloat to be just a proxy ...
    Please comment!
    • Out of curiousity, could you be more specific about the "bloat" in Apache?

      I have a few apache reverse proxies going here for various purposes and it seems like they are plenty fast and have quite a tiny footprint (and took all of about 5 minutes to set up).

      Of course it could be because all my actual apps are in mod_perl and it's only by comparison that "vanilla" apache seems small?

      • Out of curiousity, could you be more specific about the "bloat" in Apache?
        The reverse proxy for my zope is running on a old AMD K6/200 with 64 MB RAM- almost everything is bloat for that machine. Anyway in the next weeks the old machine will be gone and I plan to put the proxy on the machine where zope is running on. Still I dont want too much additional load on that machine. So much for the footprint.
        Apart from that: apache is huge and administration and configuration is not trivial and a small and simp
    • by bavarian ( 59962 ) on Tuesday December 21, 2004 @07:35PM (#11154458)

      pound (http://www.apsis.ch/pound [apsis.ch]) is a good and very secure choice. It was developed with Zope in mind, but can be used with any other http server.

      pound sanitizes http requests, does load balancing and logging, and can SSL-enable your Zope site.

    • On a related note, we actually have two layers in front of our Zope. The first is apache, which handles rewriting of virutal hosts and "cleans up" the HTTP requests.

      The second layer is pythondirector(.sf.net) which passes the HTTP (or FTP or WEBDAV) requests through to one of several ZEO servers.

      ZEO rocks. It's painless to install, and allows you to just keep chucking new CPUs at a Zope application (I'm sure there's a limit, but I know of very a popular Zope-based site that runswith just a few ZEO servers
  • What are the advantages of using Plone/Zope versus straight up python? It seems to be just another layer of complexity and slowdown.
    • by mrright ( 301778 ) <rudi&lambda-computing,com> on Tuesday December 21, 2004 @06:42PM (#11153983) Homepage
      Zope page templates (ZPT) are quite cool. But you can use them without zope in a pure python program. And the persistence and undo offered by the ZODB (Zope object database) is also quite useful.

      There are multiple backends available, and you can get really good performance and security by using the file system backend of the ZODB on top of reiser4.

      Most of the performance problems of the plone/zope combo come from plone. So my advice as someone who had the misfortune to optimize a plone/zope based commercial website: take a good look at zope, but stay the hell away from plone.
    • Reapplied, your question is this:

      "What are the advantages of using Apache+MySQL+PHP+More versus straight up C?"

      Basically, Zope plus Plone is an application stack that offers presentation, persistence, content mangement, security, and so forth. That it is written in python is a natural benefit, yes, but only an implementation decision.
    • What are the advantages of using Plone/Zope versus straight up python? It seems to be just another layer of complexity and slowdown.

      This question is like asking why use a library instead of writing everything in c from scratch.

  • I've had several failed attempts at using Plone. It's great for "power users", but what I wanted for our group was a REALLY SIMPLE site.

    When you visit the site you can either:
    * View site as usual
    * Login as an "admin"

    When logged in as an "admin" ALL I want is:
    * Create a page
    * Edit text on a page
    * Create a link on a page
    * Add a picture to the page
    * Maybe edit raw HTML, but label that "advanced"

    The folks in our group cannot handle the "clutter" (to an untrained eye) of the normal Plone screens.

    Are there a
    • Most people don't need the bells and whistles of plone. Unfortunately the stock CMF skins are _ugly_ (which is why plone was started). It took me ~2 days to write a decent set of skins for CMF. The experience gave me a much better understanding of how Zope, CMF and plone work.
    • I recently set up a wiki for one of the sites I've designed, in response to a request for a comments page. This may be simpler than you want to get, though.

      I used PmWiki [pmwiki.org] because it was really easy to initialize. There were some automated wikispam attacks, so I configured it to require a password (which humans can easily figure out) for editing. (The site doesn't have lots of people watching for vandalism and repairing it. I'm not worried about manual vandalism. Nor do I want to futz around with con

    • I'd recommend the mambo [mamboserver.com] content management system. It's template based (there are loads to download to get you started), it's expandable via modules, to add calendars, forums, document management, news articles, etc. Simple to get up and running for just about anyone. I set it up as our new company intranet, and after a few days it was being administered and populated by the HR dept (very much non techies ;-)

      It's also reputedly faster than Plone, and written using PHP, so it's simpler to mate it with other
    • It sounds like you could use a blog tool, such as PHP-based wordpress [wordpress.org], be sure to check out the CVS-version, they have a nearly-finished 1.3 in there, much better than the current stable 1.2.2 version!
      Also, writing small plugins for WP 1.3 is really easy!
    • Plone is far too complicated for what you want, I think.

      Try (in order of least to most favorite): Typo3, WebGUI, or preferrably (in my opinion) eZ Publish.

      eZ Publish requires more setup, but is considerably more flexible than the others in my list.

  • by mrright ( 301778 ) <rudi&lambda-computing,com> on Tuesday December 21, 2004 @06:36PM (#11153932) Homepage
    Zope is a nice application server, but not exactly fast. It has nice abstractions like acquisition to do very complex web applications with only a few lines of code.

    Plone adds more layers of abstraction and makes the whole even slower. It is almost as if the plone designers read a book about advanced OO concepts and wanted to implement every single concept they just learned about in a single application.

    The only way to get decent performance out of a plone/zope setup is to put a squid proxy in front of it, but that causes a lot of problems with dynamic content.

    The documentation is also horrible. If you are lucky it is just incomplete and out of date, but in most cases there is none at all.

    If you want to do a small application with less than one hit per second, go ahead. But for a big site: forget it.
    • If you actually _dive in_ to the CMF framework (the Zope product which plone is built upon), you'll discover that plone is a CMF "skin" on steroids.

      It would be far more accurate to complain about CMF than plone itself.
    • right! more abstraction layers make applications slower.
      BUT: more abstraction layers makes usually cleaner :), iirc powerful applications were not written in assembler?

      another right! on squid. if you do serious deployment of plone - you need squid. so what's the problem? there are days where plone.org get's > 1.000.000 hits per day. on a single box. with dynamic content and lots of logged in users.

      you're right with the documentation too. another but :) we just reorganized the plone.org/doc section t
    • f you want to do a small application with less than one hit per second, go ahead. But for a big site: forget it.

      Not true at all. Yes zope is slower than many other application servers. It's also vastly more powerful.

      If you want better performance, the turn off debug mode, clean up your skins so you aren't 12 layers deep and enjoy. If you really need to, with ZEO you can easily deal with the need for more processing horsepower by throwing servers at it.
    • This is a troll if I ever saw one. I usually don't respond to trolls, but when they get modded "+4 Insightful", I have to.

      Zope is a nice application server, but not exactly fast. It has nice abstractions like acquisition to do very complex web applications with only a few lines of code.

      Zope is among the fastest application servers out there, and certainly scales better than any Java-based app server I've seen due to its native support for ZEO [zope.org] (server clustering). Boston.com runs a huge Zope cluster

  • by Anonymous Coward
    Can anyone recommend a good Zope host?
    • I've been using Zettai (www.zettai.net). They are reliable, knowledgeable, and provide fast and good service. Highly recommended.
      • I also use Zettai, besides that 5+ hour downtime they had last month they have been great. As far as LAMP setup, if you have root access Zettai says you can set up anything you want.

        I imagine that you can set up Zope/Plone on any VPS or dedicated hosting plan (since you would have root).
  • I have a simple question, why is it that when open source content management is discussed, Typo3 is rarely brought up? Is it because of the complexity?

    My latest project involved changing an old static web site into one managed by a content management system. We tried Mambo, Drupal, and Zope, and then Typo3. All of the other content management systems seemed like a toy compared to Typo3.

    Typo3 is advanced enough to be compared to SAP portals and Vignette in terms of scalability, stability, and enterprise-le
  • by jm1973 ( 789334 ) on Tuesday December 21, 2004 @07:02PM (#11154183) Homepage
    I wrote Plone Content Management Essentials and it IS shallow, on purpose. In general, it's the book to hand to the PHBs if you need to explain things to them in language they understand. Or, use it to get your feet wet before jumping into the hard-core Zope site/Plone site/Andy's book, etc. Errata and TOC at thickbook.com if anyone needs it. I don't think SAMS has it online yet.
    • To me, Plone is like a huge green apple: you turn it around and around trying to figure out where to take the first bite. I struggled with the available documentation until Andy McKay's book came out. It is comprehensive, in-depth, and absolutely essential. At the same time, I definitely think *Plone Content Management Essentials* has a role to play. In fact, even for technical users and developers, I would recommend *Plone Content Management Essentials* as a good way to get started using Plone, before
  • Ruby on Rails (Score:4, Informative)

    by GnuVince ( 623231 ) on Tuesday December 21, 2004 @07:11PM (#11154257)
    A bit off topic, but according to this post [google.com], Dave Thomas's next book (of Pragmatic Programmers fame) will talk about the Ruby on Rails [rubyonrails.org] framework, the latest craze in the Ruby world.
    • by Anonymous Coward
      ...brought to you by the Obligatory Mention of Ruby in Every Python Thread Association
  • Someone throw me a life preserver! (I like the OpenACS one myself.)
  • by adpsk ( 629601 )
    Watch out for Chapter 12 in The Definitive Guide to Plone. I guess things have changed a bit with the current release of plone and as a consequence the example is broken. Luckily you can find a copy on the author's site: http://plone-book.agmweb.ca

    I only mention it, as this is the chapter on "Writing a Product in Python" which is rather important if you want to get anything interesting accomplished.

    Also, not to get too picky, but the code snippets don't match up and when you go to look for a full listing
  • what about this one?

    http://www.packtpub.com/book/plone [packtpub.com]
  • I've been reading about Plone, installed it on several servers, and doing some routine customization on one or two Plone sites. I have also been reading about Archetypes and custom content types. Honestly, my question: is Zope/Plone just too darn complicated? It has a lot of abstraction, but seems very heavy on complexity. I'm considering moving towards some sort of template-based PHP component framework as an alternative.
  • I would've rated them slightly differently, but with the same spread between them ("Definitive" getting 7, Meloni's book getting 5). McKay's book is a must have for anyone doing anything with plone, and will really be useful for anyone using Zope that plans on moving to Z3 when it arrives, as CMF is the new interface to Zope with 3.0.

    Meloni's book is largely targeted at content managers and site administrators, developers won't find it to be as useful.

  • I'm a coder of java web apps by profession. I put Zope on my site to give it a try, and I didn't want to write an image gallery for myself. What I found was that it was very hard for me to get under the covers and tweak, like I would prefer to do. I believe there to be a bug in the code of the image gallery I'm using. But for the life of me I can't look at any source code. The content management interface just keeps saying "Oh, this is a pictures folder, so your option is to add more pictures." There

Every nonzero finite dimensional inner product space has an orthonormal basis. It makes sense, when you don't think about it.

Working...