Creating a site from ready-made components on the example of a site for ordering food to the office

    There is no decent food service in the vicinity of our office, so we bring lunches to order from one cafe. The order is carried out per day (on Monday the order is made from Friday), by telephone, with a listing of all dishes and their quantity (in case the order has not changed from yesterday it is enough to simply say this). As a company engaged in software development, mainly the web, until recently we lived on the principle of “Shoemaker without boots”, and the entire accounting of orders was carried out by the person responsible for ordering food on a piece of paper, if the order was changed, it was necessary to write a letter to this responsible person, and he already recounted the general order.

    Having found some free time in the interval between projects, I implemented (I implemented it, but didn’t write - why it is so, I’ll tell you a little lower) a system for ordering food. The basis, as you can easily guess based on the topics of the blog, was taken by CMS Drupal, which has been my main tool for about a year and a half.

    The objectives of this topic:
    • Show beginners a fairly simple example of how to create a site of low complexity on CMS Drupal
    • Briefly tell about several basic modules - as a rule they are used in 90% of projects on Drupal
    • Show how you can build a site on a Drupal from ready-made components without writing a single line of code (in fact, there will be a couple of lines of code, but a little in the form that it is usually written =))


    So, what should be implemented in the project:
    • Menu - a list of dishes divided into categories, with the ability to describe dishes
    • Individual orders - the user can make an order, view its contents and change
    • Consolidated order - a list of all dishes ordered by users with an indication of their quantity
    • The ability to share experiences about dishes - here is just the possibility of commenting and rating



    I will start with a small digression. Because I mainly work with Western customers and am used to English when developing in Drupal, then all instructions, examples and screenshots will be in English (with small Russian inserts, when it will be easier to do =)). But with localization in general and with Russification in particular, everything is fine with Drupal. You can download Russification and read about localization on the website of Drupal’s domestic headquarters. Also, please note that the article lists a fairly large number of modules. The presence of a huge number of modules is a big plus and at the same time some minus when working with Drupal. The plus is that a huge amount of functionality has already been written, for using which it will be enough for us to install the module and put a couple of checkmarks in the settings. The downside is that you need to know exactly which modules you need to use to get the necessary functionality, which makes the entry point into development on the drupal quite high.

    So, bouts. The first thing we need is Drupal itself. At the time of writing, the latest stable version is 6.10. Installing Drupal should not cause any difficulties - everything, IMHO, is extremely simple and clear - the installer gives enough tips and explanations. After installation, we have a pristine-clean system. Because during development, we have a lot to go through different sections of the site, then we will start by installing the Administration menu module . This module creates a menu at the top of the page for quick navigation on the site for administration. To install the module, download it (at the time of writing, the latest stable version 6.x-1.3), unpack and put it in sites / all / modules (you will need to create the modules folder yourself, why you can read it in the Drupal documentation ). After that we go to


    Administer -> Site building -> Modules and turn on the module. Immediately after installing the module, you should see the same administrator menu at the top, with drop-down items. In general, in order for it to appear, you must give users permission for this in the Administer -> User management -> Permissions section , but since Since we are currently working under a user with UID 1, then everything is possible for us and always (therefore, they should not be tested under any circumstances). Now we need to create a new type of content that will be a description of the dish. To do this, go to Administer -> Content management -> Content types -> Add content type


    and customize everything we need. I named the content type Meal (the meal’s name is the other name), renamed Body to Description (because we will have a description here), unchecked the Promoted to front page, because we are not going to display information about dishes on the main page and twisted a bit of settings for the cameras. The foundation has been laid, and now we need to build a site on its basis. One description and name for the dish is not enough. First, we need to divide the dishes into categories (Salads, Soups, Hot, etc.), then we need the price of the dish and, add the possibility of attaching dish expressions. If we can do the first with the help of the Taxonomy module, which is included in the basic Drupal package, then for the rest we will need to install additional modules. Drupal has a module for adding fields of different types to the content of a taipa


    Content Construction Kit (CCK) . Its delivery includes both the basic module for adding additional fields, as well as a small set of frequently used field types. Download, unpack and put this module in sites / all / modules (this set of actions is the same for all all new modules, so I won’t describe it anymore, when installing a new third-party module it is implied automatically). To add a price, we need a field of type Money , which is part of the Money CCK field module . This module depends on several modules (you can find out by going to the module management section) - this is the Currency API, which is part of the Currency Exchange module , Format Number API and Formatted Number CCK. To add images to the node (the node is the name of the unit of content in the drual), you can actually use the standard file attachment module, but we want everything to be beautiful, and therefore we will use a custom field for uploading images. To implement this, we will need ImageField and ImageCache modules , as well as their dependencies - FileField and ImageAPI .

    We take all of the above modules from the section Official releases . And although some of the modules from the list have not yet reached a stable version, I personally did not notice any problems during their operation.

    So, after all the modules have been downloaded and placed where we need to go to the module management section (Administer -> Site building -> Modules ) and tick off the modules we need. And we need the following - ImageField , Money CCK field , ImageCache , ImageCache UI , ImageAPI GD2 and Taxonomy (should be installed by default, but if not, then install). All the modules he needs will be installed automatically (there is a small error in the installer of the Money CCK field module version 1.0, and he will get a message stating that his dependencies are not installed, although they are installed automatically, so you will have to check this module again and start the installation).

    Now create a profile for the uploaded dish images. For this, we needed the ImageCache module. We go to Administer -> Site configuration -> By module (here, because ImageCache UI for some reason doesn’t put a link to its settings in the general list), look for the ImageCache UI module and go to its only possible configuration option - ImageCache . Create a new set of settings (Add new preset). Call it meal_img and add the Scale action (scaling). Specify 120 (pixels) in the Width field , and delete the value from the Height field . Then our images will be scaled in accordance with the proportions and reduced relative to the width.

    Now create the categories by which we will share the dishes. To do this, go to Administer -> Content management -> Taxonomy -> Add vocabulary and fill in the fields:
    - Vocabulary name - Category
    - Content types - Meal
    - Required
    Then we go to the add terms section of our dictionary and create several categories (terms). Now we can move on to adding the fields we need to the previously created Meal content type. To do this, go to Administer -> Content management -> Content types -> Edit Meal -> Manage fields and create the necessary fields. And we need the following fields:



    1. Label : Cost , Field Name : field_cost , Type : Money , Form element : Amount and currency , after creating, select the display type and currency that is convenient for us (for some reason I always thought that the Russian ruble is RUR, and here for some reason RUB) and do field is a mandatory field ( required )
    2. Label : Pictures , Field Name : field_pictures , Type : File , Form element : Image , this field is not required, and the maximum Number of values can be set, for example, to 3, and twist the settings a bit so that users have it’s easier to add new dishes to the menu.



    Now we need to configure the display of the nodes. To do this, go to Administer -> Content management -> Content types -> Edit Meal -> Display fields -> Basic . Here for the Pictures field you need to set:
    - Teaser -
    - Full node - meal_img image linked to image (for this we created a preset)
    For the Cost field, you can set the Label field to Inline so that the label for the field is on the same line with the value. Well, now it's time to finally create some instances of dishes for further testing. To do this, go to Create content -> Meal and fill in the fields. Repeat this action several times. Add a couple of dishes to each category. Next, we add to the dishes the actual possibility of ordering and a rating system (just like that =)). The Flag modules and Fivestar module will help us with this , for which you will need to install the same





    Voting API. Качаем эти модули, идем в панель управления модулями и включаем Flag и Fivestar. После установки, необходимо настроить модули. Для этого сначала идем в Administer -> Site configuration -> Fivestar и выбираем стиль, который вам нравится больше всего (я выбрал Basic с желтым набором цветов, наведя курсор на звездочки можно сразу увидеть как они будут выглядеть). Теперь нужно активировать систему рейтингов для контента, реализующего блюда. Для этого идем в Administer -> Content types -> Edit Meal и в разделе Fivestar ratings ставим галку Enable Fivestar rating, и выставим значение поля Teaser display в Clickable widget below teaser (useful to us later). You can twist the rest of the settings to your taste. Now, briefly distract from the content and make a few settings for users. Our resource for ordering food will be internal, but it will be located on a global network, so we need to somehow protect it. To do this, we first turn off the possibility of registering new users (when applying for a job, our system administrator sets up accounts in the systems we use - mail, forum, base camp, now also in the food ordering system). You can do this by going to Administer -> User management -> User settings and setting the Public registrations switch to Only site administrators can create new user accounts


    . Now go to Administer -> User management -> Roles and add a new role (I called it HabraUser). Now configure the permissions. To do this, go to Administer -> User management -> Permissions , remove all rights from the anonymous user and authenticated user groups , and give the HabraUser group the following set of rights:
    - comment module : access comments, post comments, post comments without approval
    - fivestar module : rate content
    - node module : access content
    - user module : access user profiles


    Now, finally, add the ability to order dishes. To do this, create and configure a new flag. To do this, go to Administer -> Site building -> Flags -> Add and create a flag with the name meal_order and type Nodes . We set different labels (you can see my variant on the screenshot to this paragraph), allow only users from the HabraUser group to use this type of flag, and apply this flag only to nodes of the Meal type . We will show the flag both in the teaser and on the page. We will leave Link type in the JavaScript toggle value - then the flag will switch using AJAX.


    Well, 2/3 of the path is covered. Now it remains to make the menu display, the display of the user order and the collective order. We proceed to the implementation of these points.

    To implement all kinds of lists in Drupal, there is a very flexible module Views , which we will use. Download, go to the module control panel and turn on Views (kernel) and Views UI (admin interface for managing views). Now create a view to display dishes from different categories, for this, go to Administer -> Site building -> Views -> Add and create a menu with the name meal_menu and the type Node. Then we get to the view management page. Initially, we do not have mappings, and we can configure the parameters common to all mappings. I made the following settings:
    • Basic settings
      • Row style : Node -> Display only teaser, Display links (display nodes completely, show only teaser and links - in the links we will have the order flag)
      • Items to display : 0 (all dishes on one page)
      • Access : Role -> HabraUser

    • Sort criteria
      • Node: Post date : Ascending (here you can choose what you like best)

    • Filters
      • Node: Published : Yes
      • Node: Type : Is one of -> Meal


    As a result, it should turn out the same as in my screenshot (just changed fields are highlighted in bold). Click the Save button and save the current state of the base view. Now create specific pages for each category of dishes, inheriting all the pages from the base. To do this, in the left column of the view settings, select the Page display type in the drop-down list (usually selected by default) and click the Add display button


    and immediately see how we have added a new view mapping. Since this is a specific display - it has slightly changed the set of parameters - menu options were added, and the general view settings disappeared. Now we need to redefine some parameters of the base view. The first thing we need is to add a filter to the tarmin from the dictionary of taxonomy categories. To do this, add a new Taxonomy: Term filter and in it:
    • Vocabulary - Category (we have, in fact, only one)
    • Selection type - Dropdown
    • Operator - Is one of
    • Select terms from vocabulary Category - Hot (only one term needs to be selected)


    Now a very important action - you need to click the Override button so that this filter applies only to this display instance. Otherwise, it will apply to the base display. Now click Update, which will save our new filter. Next, give the display a name and a title by the name of the term. Those. change the Name and Title parameters in Basic settings (here it will also be necessary to click Override to redefine the parameter, relative to the basic display) to Hot . Now, in order to be able to get to the page that implements this type of display, you must set the path for it. This is done in the Page settings section , for example meal_menu / hot. Save the view (until then, all actions were recorded in a temporary repository, and can easily be canceled). Now we repeat the same actions, but for all other taxonomy terms. As a result, you should get 3 (I have 3 terms in the dictionary, how many categories of dishes will be in the menu, so many terms) of the display implementation. For me they have the following names / headers and paths:



    • Hot - meal_menu / hot
    • Salads - meal_menu / salad
    • Soups - meal_menu / soup

    You can see what happened by clicking on the links of the View "Salads" type located at the top. Now that we have the constituent parts of the menu, in the form of lists of dishes by category, it's time to take up the menu itself. To do this, use the Panels module . At the time of writing, there is no stable version of the module for the sixth version of Drupal. There are 2 versions of the module that are in the alpha version - 6.x-3.0-alpha2 and 6.x-2.0-alpha3 , i.e. quite early. Although version 2.0 is recommended, we will still use version 3.0, if only because it is newer. And from experience with use, I can say that according to my subjective feelings, the stability of these two beliefs is approximately at the same level, and quite high. Version


    6.x-3.0-alpha2 also has a Chaos tool suite module in interchangeability . Download and go to the module control panel. We activate the following modules - Chaos tools , Delegator , Panels and Views panes .

    Now create the page itself with the menu. To do this, go to Administer -> Site building -> Pages -> Add page . Set the name and path for the page (in my case, both meal_menu) Next, we add the access rule to the page (as you remember, we are creating a site for internal use, but with access via the Internet, so we will only give access to the group we created). Because menu is the main functional page of the site, then add a link to it in the main menu. To do this, select in the Type Normal menu entry , set the title (I have this Meal Menu) and select in the Menu Primary links . Next, select a single handler for our page ( Create a single handler for this page ) and set it to Panel (to be honest, I never used multiple handlers). Now configure the handler. We set the same access level for it as for the page. Of the patterns suits us betterThree column 33/34/33 (one category per column, although on a live site I have more categories in the same 3 columns). Next, we’ll set a title for the page (for example, the Meal Menu) and choose a style for the panel (I advise Rounded corners, because this style by default gives a fairly large and convenient distance between columns). And finally, add to the columns the views we created earlier - meal_menu: Hot , meal_menu: Salads , meal_menu: Soups . If you want to change the order of the views in a column or change the column for some views - just drag and drop them - Drag & Drop works stably. Finally, click Finish and ... we don’t notice absolutely no changes =) The thing is that the module


    Panels uses its system to determine user accessibility, so a user with UID 1 has no privileges. As we recall, access to the menu was given only to users from the HabraUser group, so just add ourselves to this group. To do this, go to edit your profile ( My account -> Edit ) and in the Account information section put the HabraUser checkbox in the Roles field and save the profile. Now a menu item has appeared in the main menu, which will lead us to the page with the menu. Now we can place an order, and move on to the next part =) After the order is placed, we are interested to see our order in our profile. To do this, again, use the capabilities of the Views module. Go to


    Administer -> Views -> Add and create a view named user_meal_order with type Node . In the base mapping (I would compare it with the abstract base class in OOP) we make the following settings:
    • Basic settings
      • Style : HTML List -> Unordered list
      • Items to display : 0 (all)

    • Relationshipships
      • Flags: Node flag -> Include only flagged content, Flag : Food Order, By : Current user

    • Fields
      • Node: Title -> Label : <empty value>, Link this field to its node

    • Sort criteria
      • Flags: Flagged time -> Ascending

    • Filters
      • Node: Published -> Yes


    Now add a new mapping of type Block and add the following settings:
    • Basic settings
      • Title : My order (do not forget to click Override before saving the parameter to redefine it, and not change it in the base display)


    Save the view and go to the Administer -> Blocks -> List block control panel . There, in the list we find our block, user_meal_order: Block , and add it to the Left sidebar region. For convenience, drag the block to the very bottom of the list of blocks in the region. Save the block settings. We see that the block appeared in the left panel. But I think that it’s not very nice for this block to hang on all pages. Let’s make the block visible only in the owner’s profile. To do this, click configure next to our block and get to the page for editing block settings. Here we are interested in the Page specific visibility settings section . Set the Show block on specific pages parameter toShow if the following PHP code returns TRUE (PHP-mode, experts only) and write the following in the input field (yes, this is the first piece of code =)): Thanks to user brmn for a hint in optimizing this piece of code. With this piece of code, we check if the current page is a user profile, and if so, is it our profile. After saving, the block with our order disappeared, and now you can see it only by going to your profile. The last thing that remains for us to implement is a collective order, i.e. a list of all ordered dishes with an indication of their quantity. To do this, again, use the Views module. For this page we will need an additional module, so go to the module control panel and enable PHP filter

    global $user;
    return (arg(0) == 'user' && arg(1) == $user->uid);
    ?>







    (comes as standard). Now go to Administer -> Views -> Add and create a view called meal_order with type Node . We change the parameters of the base display as follows:
    • Basic settings
      • Style : HTML List -> Unordered list
      • Row style (settings, gear icon, will need to be done after the Fields item has been completed): Mark both fields and enter "-" as a separator
      • Items to display : 0
      • Distinct : Distinct (otherwise, we will have as many lines with one dish, how many times it is ordered)
      • Access : Role -> HabraUser

    • Relationshipships
      • Flags: Node flag : Include only flagged content, Flag : Food order, By : Any user
      • Flags: Node flag counter : Include only flagged content, Flag : Food order

    • Fields
      • Node: Title : Label : <empty value>, Link this field to its node
      • Flags: Flag counter : Label : <empty value>

    • Sort criteria
      • Node: Post date -> Ascending

    • Filters
      • Node: Published -> Yes


    Then we add a new display of the Page type and redefine the following parameters in it in the Basic settings section :
    • Title : Summary Order
    • Header : Display even if view has no result , Input format : PHP code and in the input field we hammer the following (yes, the second piece of code =))

      Date: 0 && date ('w') <5)? date ('dmY', strtotime ('+ 1 day')): date ('dmY', strtotime ('next Monday'))); ?>


      Those. print the date of the next day, if we have now Mon-Thu, or Monday, otherwise.

    Now, in the Page settings section, set the path ( meal_order ) and create a link in the main menu ( Normal menu entry ). We save and see in the main menu a link to a page with a general order has been added, where you can go and make sure that the selection is working. Now you can upload the system to the Internet and create accounts for your colleagues ( Administer -> User management -> Users -> Add user ). Additionally, the standard Drupal theme provides CSS for convenient printing of pages. That's just about everything that I was going to tell in this article. All that was planned in the project is achieved. Whether the goals of the topic are reached is up to the readers to decide. Waiting for feedback and questions.







    PS: It took about 2.5 hours to create a live version of the site for my company. At this time, it included driving in about a hundred names of dishes (though without images).

    UPD : For those
    interested in the topic of development on Drupal, I can recommend a wonderful book, according to which I studied myself at one time - everything is quite clear and described in detail in it (though in the second edition I found an error in the code =)). The book is called Pro Drupal Development ( Apress Publishing House , ISBN 9781430209898) There are 2 such books in nature - the first and second edition. The first describes Drupal 5, the second edition is Drupal 6. Finding them online is easy. I advise you to read books in the original, i.e. in English. Because I don’t know anything about the existence of the second edition in Russian, but the first one was recently bought at the office (after half a year I switched to D6) - it’s kind of subtle, the feeling that they cut something there.

    Also popular now: