Jump to content

Pages: tutorial paso a paso


admin
 Share

Recommended Posts

https://invisionify.com/pages-tutorials/documentation/

Documentation like IPS guides

In this tutorial we build a documentation section à la IPS help guides. We will not build the documentation exactly the same, however you can customize, extend or adapt it to your needs at any time once you have understood the basic structure. 

The database for the documentation uses the categories to divide it into the larger sections. A kind of chapter. In each chapter (category) there are several pages that are subordinated to the category. In the original IPS documentation, categories have a three-level hierarchy. I find it overloaded, confusing and difficult to navigate. Therefore, we will limit the guide to two-level categories in this tutorial.

Who is this tutorial for?

You need to understand HTML, JavaScript and some PHP to make it with ease. The database itself is very simple. The most interesting part is the menu on the left side (a block). And a page template with the sidebar is on the left side (opposed to the default look of most communities, where the sidebar is on the right). We will not change the community in general, only for the documentation, so that the rest of the community pages will still have the sidebar on the right.

Attention! The interaction in the left menu with expanding and collapsing categories or marking the current pages works ONLY if you have set up and use friendly URLs to your community. 

Link to comment
Share on other sites

Create database

We are going to create a database that contains categories and assign the key doc for the database. In your AdminCP go to Pages -> Contents -> Databases and click on Create new.

On the tab Details check that the database use categories, otherwise you will not be able to create a menu block. The key of the database should be set to docs. Use default templates as shown in the screenshot below, we will change them later where necessary.

Create database

On the next tab you set the language. This documentation consists of guides / pages, so we will use the word "guide" here, instead of entry or record.

Language tab for documentation

On the next tab Options we change some settings as we do not need some features in this database. We will not allow comments or reviews. The record image is not important in this database as well.

database-options.png

 

We skip the tabs Forums and SEO, there is nothing to change here. On the last tab Page we will create a new page so that we can access the database to test it during this tutorial. You cannot use a database in IPS if you do not assign it to a page!

Tab Page for Database

We do not create the page with Page Builder, but with manual HTML. The reason is that we want to "reverse" the page structure, so that the sidebar with navigation will be displayed on the left side. You can't do it with Page Builder unless you create a new page template first. This would be useful if you want to build several pages like this. For example, if you have several databases that use this structure.

But for our purposes manual HTML is enough. Remember to turn off the standard community sidebar. Otherwise, your documentation would have three columns (navigation, main content and community sidebar on the right). There will be not enough space for the main content if you have three columns.

In the permissions' matrix you can set what group should get what permissions for the documentation. Remember that we have disabled comments and reviews for the database, so you can safely omit these permissions for all groups. 

Add page to menu

After the database and page have been created, you add this page to the main menu of your community so that you can access it quickly. Or you have to call the database via https://example.com/docs and that is a bit awkward. In AdminCP go to System -> Site Features -> Menu Manager and click on Add Item. On the right side in the Menu Item Type area choose Page. Then in the Configuration section below select the page with the documentation from the drop down list.

Add menu item for the database

Save the menu item and do not forget to Publish this menu. Switch to your community and view the page.

If you do not see the menu item, then most likely the permissions for the page are not set. In AdminCP go to Pages -> Page management -> Pages, click on the arrow down in the line containing the page docs and select Permissions. Now you should be able to see the page in the main menu of your community.

Link to comment
Share on other sites

Add a Custom Field

To avoid the navigation block be too heavy, we can optionally create a field that contains a short version of the page title. An example for the long title of the page can be "General introduction to databases with Pages". This page title is too long for the left navigation. It would be nicer if we could output a shorter version here, for example "Introduction". 

Create field for short version

In AdminCP go to Pages -> Documentation -> Fields and click on Create new. Fill out the form on the tab General Options as shown below:

Create a custom field

Note that the field is set as not required so that we don't have to fill it for every guide. Some guide titles will be suitable for navigation without shortening. Then go to the tab Display.

Display options for custom field

Template Key must be shortened_title. If you change it here, you will have to change the key later in the templates. That means it will not work just with copy/paste! This field is a helper field that is used to replace too long guide titles in the navigation. This field should not be visible in the listing or in the guide template. Turn off the both display options.

Link to comment
Share on other sites

Create Templates

Now it is time to create templates for the database. In your AdminCP go to Pages -> Page management -> Templates. Click on New and select Add Database Template. Enter Docs in the Name field and select Record listing in Template Type. Assign the template to our database Documentation.

create-new-database-template.png

A new template set Docs will be created. It contains several template bits for the listing of the records.

Let's add another set of template bits to it. It will handle displaying the records in the database. Execute exactly the same steps as in the previous step (see screenshot above), except that you choose Record in Template Type. When you save it, you will have a template set called Docs on the left side, which contains all the required template bits.

Template set for database

Below you will find the code for each template bit.

Display record - Template bit record

This template controls the display of single guide page so-called main content. Before you replace the code of this template, you can look at a single guide in documentation and see how it is visually structured. Then replace the content of the template with the code below and look at the page again. This is the best way to see what has changed.



{{if $record::database()->can('add') or \IPS\Member::loggedIn()->member_id}}
<ul class="ipsToolList ipsToolList_horizontal ipsClearfix ipsSpacer_both ipsResponsive_hidePhone">
    {{if $record::database()->can('add')}}
    {{$page = \IPS\cms\Pages\Page::$currentPage;}}
    <li class='ipsToolList_primaryAction'>
        <a class="ipsButton ipsButton_medium ipsButton_important ipsButton_fullWidth" data-ipsDialog="1" data-ipsDialog-size="narrow" data-ipsDialog-title="{lang="cms_select_category"}" href="{$page->url()->setQueryString( array( 'do' => 'form', 'd' =>
        \IPS\cms\Databases\Dispatcher::i()->databaseId ) )}">{lang="cms_add_new_record_button" sprintf="$record::database()->recordWord( 1 )"}</a>
    </li>
    {{endif}}
</ul>
{{endif}}

<div class='ipsClearfix'>
    <h1 class='ipsType_pageTitle ipsType_break'>
        {{if $record->locked()}}<span><i class='fa fa-lock'></i></span> {{endif}}

        {{if $record->isFutureDate() || $record->mapped('pinned') || $record->mapped('featured') || $record->hidden() === -1 || $record->hidden() === 1}}
        {{if $record->isFutureDate()}}
        <span><span class="ipsBadge ipsBadge_icon ipsBadge_warning" data-ipsTooltip title='{$record->futureDateBlurb()}'><i class='fa fa-clock-o'></i></span></span>
        {{elseif $record->hidden() === -1}}
        <span><span class="ipsBadge ipsBadge_icon ipsBadge_warning" data-ipsTooltip title='{$record->hiddenBlurb()}'><i class='fa fa-eye-slash'></i></span></span>
        {{elseif $record->hidden() === 1}}
        <span><span class="ipsBadge ipsBadge_icon ipsBadge_warning" data-ipsTooltip title='{lang="pending_approval"}'><i class='fa fa-warning'></i></span></span>
        {{endif}}
        {{if $record->mapped('pinned')}}
        <span><span class="ipsBadge ipsBadge_icon ipsBadge_positive" data-ipsTooltip title='{lang="pinned"}'><i class='fa fa-thumb-tack'></i></span></span>
        {{endif}}
        {{if $record->mapped('featured')}}
        <span><span class="ipsBadge ipsBadge_icon ipsBadge_positive" data-ipsTooltip title='{lang="featured"}'><i class='fa fa-star'></i></span></span>
        {{endif}}
        {{endif}}

        {{if $record->prefix() OR ( $record->canEdit() AND $record::canTag( NULL, $record->container() ) AND $record::canPrefix( NULL, $record->container() ) )}}
        <span {{if !$record->prefix()}}class='ipsHide'{{endif}} {{if ( $record->canEdit() AND $record::canTag( NULL, $record->container() ) AND $record::canPrefix( NULL, $record->container() ) )}}data-editablePrefix{{endif}}>
				{template="prefix" group="global" app="core" params="$record->prefix( TRUE ), $record->prefix()"}
			</span>
        {{endif}}
        {{if $record->canEdit()}}
        <div class='ipsType_break ipsContained' data-controller="core.front.core.moderation">
            <span data-role="editableTitle" title='{lang="click_hold_edit"}'>{$record->_title}</span>
        </div>
        {{else}}
        <div class='ipsType_break ipsContained'>{$record->_title}</div>
        {{endif}}
    </h1>

</div>

{{if count( $record->tags() ) OR ( $record->canEdit() AND $record::canTag( NULL, $record->container() ) )}}
{template="tags" group="global" app="core" params="$record->tags(), FALSE, FALSE, ( $record->canEdit() AND $record::canTag( NULL, $record->container() ) ) ? $record->url() : NULL"}
{{endif}}

<article class='ipsContained ipsSpacer_top'>
    <div class='ipsClearfix'>
        <section class="ipsType_richText ipsType_normal" data-controller='core.front.core.lightboxedImages,guides.menu'>{$record->_content|raw}</section>

        {{if $record->editLine()}}
        {$record->editLine()|raw}
        {{endif}}

        {{if $records = $record->getReciprocalItems()}}
        {{$infoLineShown = FALSE;}}
        <br>
        {{foreach $records as $fieldId => $items}}
        <ul class="ipsList_inline ipsList_csv ipsList_noSpacing">
            {{foreach $items as $item}}
            <li>{{if ! $infoLineShown}}{{$infoLineShown=TRUE;}}{lang="records_linking_to_me" sprintf="$item::database()->recordWord(0,TRUE), $record::database()->recordWord(1)"}: {{endif}}<a href="{$item->url()}">{$item->_title}</a></li>
            {{endforeach}}
        </ul>
        {{endforeach}}
        {{endif}}
    </div>
    {{if $bottomFields = $record->customFieldsForDisplay('display_bottom')}}
    <hr class='ipsHr ipsClear ipsClearfix'>
    {{foreach $bottomFields as $fieldId => $fieldValue}}
    {{if $fieldValue}}
    {$fieldValue|raw}
    {{endif}}
    {{endforeach}}
    {{endif}}
    {{if $record instanceof \IPS\Content\Reputation and settings.reputation_enabled}}
    <div class='ipsPos_right'>
        {template="reputation" app="core" group="global" params="$record"}
        <br>
    </div>
    {{endif}}
    <hr class='ipsHr ipsClear ipsClearfix'>
    {{if $record->isFutureDate() or $record->canPin() or $record->canUnpin() or $record->canFeature() or $record->canUnfeature() or $record->canHide() or $record->canUnhide() or $record->canMove() or $record->canLock() or $record->canUnlock() or $record->canDelete()}}
    <a href='#elentryActions_menu' id='elentryActions' class='ipsButton ipsButton_light ipsButton_verySmall' data-ipsMenu>{lang="content_record_actions" sprintf="$record::database()->recordWord( 1, TRUE )"} <i class='fa fa-caret-down'></i></a>
    <ul id='elentryActions_menu' class='ipsMenu ipsMenu_auto ipsHide'>
        {{if $record->isFutureDate() and $record::canFuturePublish( NULL, $record->container() )}}
        <li class='ipsMenu_item'><a href='{$record->url('moderate')->csrf()->setQueryString( array( 'action' => 'publish' ) )}' data-confirm title='{lang="publish_now"}'>{lang="publish"}</a></li>
        {{endif}}
        {{if $record->canFeature()}}
        <li class='ipsMenu_item'><a href='{$record->url('moderate')->csrf()->setQueryString( array( 'action' => 'feature' ) )}' title='{lang="feature_title_record" sprintf="$record::database()->recordWord(1)"}'>{lang="feature"}</a></li>
        {{endif}}
        {{if $record->canUnfeature()}}
        <li class='ipsMenu_item'><a href='{$record->url('moderate')->csrf()->setQueryString( array( 'action' => 'unfeature' ) )}' title='{lang="unfeature_title_record" sprintf="$record::database()->recordWord(1)"}'>{lang="unfeature"}</a></li>
        {{endif}}
        {{if $record->canPin()}}
        <li class='ipsMenu_item'><a href='{$record->url('moderate')->csrf()->setQueryString( array( 'action' => 'pin' ) )}' title='{lang="pin_title_record" sprintf="$record::database()->recordWord(1)"}'>{lang="pin"}</a></li>
        {{endif}}
        {{if $record->canUnpin()}}
        <li class='ipsMenu_item'><a href='{$record->url('moderate')->csrf()->setQueryString( array( 'action' => 'unpin' ) )}' title='{lang="unpin_title_record" sprintf="$record::database()->recordWord(1)"}'>{lang="unpin"}</a></li>
        {{endif}}
        {{if $record->canHide()}}
        <li class='ipsMenu_item'><a href='{$record->url('moderate')->csrf()->setQueryString( array( 'action' => 'hide' ) )}' title='{lang="hide_title_record" sprintf="$record::database()->recordWord(1)"}' data-ipsDialog data-ipsDialog-title="{lang="hide"}">{lang="hide"}</a></li>
        {{endif}}
        {{if $record->canUnhide()}}
        <li class='ipsMenu_item'><a href='{$record->url('moderate')->csrf()->setQueryString( array( 'action' => 'unhide' ) )}' title='{{if $record->hidden() === 1}}{lang="approve_title_record" sprintf="$record::database()->recordWord(1)"}{{else}}{lang="unhide_title_record" sprintf="$record::database()->recordWord(1)"}{{endif}}'>{{if $record->hidden() === 1}}{lang="approve"}{{else}}{lang="unhide"}{{endif}}</a></li>
        {{endif}}
        {{if $record->canLock()}}
        <li class='ipsMenu_item'><a href='{$record->url('moderate')->csrf()->setQueryString( array( 'action' => 'lock' ) )}' title='{lang="lock_title_record" sprintf="$record::database()->recordWord(1)"}'>{lang="lock"}</a></li>
        {{endif}}
        {{if $record->canUnlock()}}
        <li class='ipsMenu_item'><a href='{$record->url('moderate')->csrf()->setQueryString( array( 'action' => 'unlock' ) )}' title='{lang="unlock_title_record" sprintf="$record::database()->recordWord(1)"}'>{lang="unlock"}</a></li>
        {{endif}}
        {{if $record->canMove()}}
        <li class='ipsMenu_item'><a href='{$record->url('move')->csrf()}' data-ipsDialog data-ipsDialog-title="{lang="move"}"  title='{lang="move_title_record" sprintf="$record::database()->recordWord(1)"}'>{lang="move"}</a></li>
        {{endif}}
        {{if $record->canDelete()}}
        <li class='ipsMenu_item'><a href='{$record->url('moderate')->csrf()->setQueryString( array( 'action' => 'delete' ) )}' data-confirm  title='{lang="delete_title_record" sprintf="$record::database()->recordWord(1)"}'>{lang="delete"}</a></li>
        {{endif}}
        {{if \IPS\Member::loggedIn()->modPermission('can_view_moderation_log')}}
        <li class='ipsMenu_sep'><hr></li>
        <li class="ipsMenu_item"><a href='{$record->url()->csrf()->setQueryString( array( 'do' => 'modLog' ) )}' data-ipsDialog data-ipsDialog-title='{lang="moderation_history"}'>{lang="moderation_history"}</a></li>
        {{endif}}
    </ul>
    {{endif}}
    {{if $record->canEdit()}}
    &nbsp;&nbsp;<a href='{$record->url('edit')->csrf()}' title='{lang="edit"}'>{lang="edit"}</a>
    {{endif}}
    {{if !\IPS\Member::loggedIn()->group['gbw_no_report'] }}
    &nbsp;&nbsp;<a href='{$record->url('report')}' data-ipsDialog data-ipsDialog-size='medium' data-ipsDialog-title="{lang="content_record_report" sprintf="$record::database()->recordWord( 1, TRUE )"}" data-ipsDialog-remoteSubmit data-ipsDialog-flashMessage="{lang="report_submit_success"}" title="{lang="content_record_report" sprintf="$record::database()->recordWord( 1, TRUE )"}">{lang="content_record_report" sprintf="$record::database()->recordWord( 1, TRUE )"}</a>
    {{endif}}
    {{if $record->canManageRevisions()}}
    &nbsp;&nbsp;<a href='{$record->url('revisions')}' title="{lang="content_view_revisions"}">{lang="content_view_revisions"}</a>
    {{endif}}
</article>

<br>
{{if $updateForm}}
<div class='ipsAreaBackground_light ipsPad'>
    <h2 class='ipsType_sectionHead'>{lang="cms_front_update_fields" sprintf="$record::database()->recordWord( 1 )"}</h2>
    <ul class='ipsForm ipsForm_vertical'>
        {$updateForm|raw}
    </ul>
</div>
{{endif}}

Some features such as rating have been removed from the template as they are not needed in the documentation. This way template looks cleaner and readable. Another approach is to leave everything inside when you create your own templates, even what is not used at the moment, but possibly later.

Categories - Templates categoryHeader, categoryFooter and categoryTable

These three templates control the list of records in a category. In my example it would be the category Applications where I have created three pages. Look first how it looks now and then delete/replace the code as shown below.

Open the template categoryHeader and delete the whole content. Save.

Open the template categoryFooter and delete the whole content. Save.

Open the template categoryTable and add the following code:



<div class='ipsPad'  data-baseurl='{$table->baseUrl}' data-resort='{$table->resortKey}' data-controller='core.global.core.table{{if $table->canModerate()}},core.front.core.moderation{{endif}}'>
	{{if !count($rows)}}
		<div class="ipsPad">
			{lang="cms_no_records_to_show" sprintf="\IPS\cms\Databases::load( \IPS\cms\Databases\Dispatcher::i()->databaseId )->recordWord()"}
		</div>
	{{else}}
		<ol class='ipsDataList ipsDataList_zebra ipsClear cCmsListing {{foreach $table->classes as $class}}{$class} {{endforeach}}' id='elTable_{$table->uniqueId}' data-role="tableRows">
			{{foreach $rows as $row}}
				{{$idField = $row::$databaseColumnId;}}
				<li class="cDocs_row " data-rowid="{$row->$idField}">
					<h4 class="ipsType_sectionHead">
						<a href="{$row->url()}" class="ipsType_blendLinks">
							{$row->_title}
						</a>
					</h4>
					<div class="ipsType_normal ipsType_richText" data-ipstruncate="" data-ipstruncate-type="remove" data-ipstruncate-size="3 lines">
						{$row->truncated()|raw}
					</div>
				</li>
			{{endforeach}}
		</ol>
	{{endif}}
</div>

At this point the list of all pages in a category is created with text preview. This list will not be accessible later via the navigation. However, users from the search engines will land here, since category links are included in the sitemap.

Link to comment
Share on other sites

Plugin for side menu

Now we are ready to create a block (plugin) that we will use as a side menu. The side menu displays categories and the pages hierarchically. This block is created in AdminCP, and we are going to use a custom template for it.

Block with page menu

In your AdminCP go to Pages -> Page management -> Blocks and click on Create new block.

Create new block

Click on Next. On the tab Details enter the name for the block and template key docs_side_menu.

Create Block, tab Details

In the tab Feed Configuration set the following:

Create Block - tab Feed Configuration

You define here the number of records in the block. In earlier versions of IPS it was possible to enter a 0 for unlimited. Starting with IPS version 4.4.10 it does not work anymore, so you have to enter a large positive number, e.g. 100. This number should be greater than the number of all categories and all pages in the categories together, otherwise the menu will be cut off.

The sorting in the block is only valid for the order of the pages within a category. The categories are sorted as specified in AdminCP. You can change their order by drag and drop.



{{$recordClass = null;}}
{{$catClass = null;}}

{{if count($records)}}
{{$recordClass = get_class($records[0]);}}
{{$catClass    = '\IPS\cms\Categories' . $recordClass::database()->_id;}}
{{endif}}

{{$firstRecord = null;}}
{{$currentUrlPath = \IPS\Request::i()->url()->data['path'];}}

{{if count($records) and $catClass and count($catClass::roots())}}
<ul class="ipsList_reset cDocs" data-controller="docs.front.devDocs.main">
    {{foreach $catClass::roots() as $root}}
    <li>
        <h2>{$root->_title}</h2>
        {{if count($root->children())}}
        <ul class="ipsList_reset">
            {{foreach $root->children() as $child}}
            <li class="cDocs_closed">
                <h3 data-action="expandSection">{$child->_title}</h3>
                {{foreach $records as $record}}
                {{if $record->container()->_id == $child->_id}}
                <ul class="ipsList_reset">
                    {{if $firstRecord == null}}
                    {{$firstRecord = $record;}}
                    {{endif}}
                    <li>
                        <a {{if $currentUrlPath === $record->url()->data['path']}}class="cDocs_active"{{endif}} href="{$record->url()}">
                            {{if $record->customFieldDisplayByKey('shortened_title', 'raw')}}{$record->customFieldDisplayByKey('shortened_title', 'raw')}{{else}}{$record->_title}{{endif}}
                        </a>
                    </li>
                </ul>
                {{endif}}
                {{endforeach}}
            </li>
            {{endforeach}}
        </ul>
        {{endif}}
        <ul class="ipsList_reset">
            {{foreach $records as $record}}
            {{if $record->container()->_id == $root->_id}}
            {{if $firstRecord == null}}
            {{$firstRecord = $record;}}
            {{endif}}
            <li>
                <a {{if $currentUrlPath === $record->url()->data['path']}}class="cDocs_active"{{endif}} href="{$record->url()}">
                    {{if $record->customFieldDisplayByKey('shortened_title', 'raw')}}{$record->customFieldDisplayByKey('shortened_title', 'raw')}{{else}}{$record->_title}{{endif}}
                </a>
            </li>
            {{endif}}
            {{endforeach}}
        </ul>
    </li>
    {{endforeach}}
</ul>
{{endif}}

{{if $recordClass and \IPS\cms\Pages\Page::$currentPage and (string) \IPS\cms\Pages\Page::$currentPage->url() == (string) \IPS\Request::i()->url()}}
{{if $firstRecord}}
{{\IPS\Output::i()->redirect($firstRecord->url(), '', 302);}}
{{else}}
{{\IPS\Output::i()->redirect(\IPS\Http\Url::internal(''), '', 302);}}
{{endif}}
{{endif}}

Save the block and give all user groups the permission to see the block. If you exclude the groups here, the menu will not be displayed for them. You can already see the rough structure of the menu in the preview of the block. We will add the CSS styles and JavaScript later to make it a bit smarter. Some CSS classes are already built into templates above.

The last lines in the block redirects from category listing to the first record in the category if you navigate through the side menu. 

Insert menu into the page

To add the block into the page, go to Pages -> Page Management -> Pages in AdminCP and click on the pencil icon to edit the page docs. Go to the tab Content. Here you can see that the database has already been added to the page via the database ID. This happened automatically when we created the page during database creation.

Replace the content of the page with the following code:



<div class="ipsBox ipsPad">
<div class="ipsColumns ipsColumns_collapsePhone" id="elDocs_columns">
  {{if \IPS\Request::i()->do !='edit' and \IPS\Request::i()->do !='form'}}
	<div class="ipsColumn ipsColumn_wide">
		{block="docs_side_menu"}
	</div>
  {{endif}}
	<div class="ipsColumn ipsColumn_fluid">
		<div class="ipsPad ipsSpacer_top">
          <div class="ipsSpacer_top">
			{database="docs"}
          </div>
		</div>
	</div>
</div>
</div>

Take time and look at this simple HTML for the page. Here we use the keys for database and the block with the menu. These are inserted in two columns using the IPS CSS framework. The IF-query makes sure that the menu disappears when you edit the page, otherwise you would not have enough space to edit the content. 

See your documentation in the frontend now. The only things we miss here are CSS and JavaScript.

Link to comment
Share on other sites

CSS and JavaScript

We have already included some CSS classes in the templates. And now we can add the CSS styles to the page. 

Create and assign CSS file

In your AdminCP go to Pages -> Page management -> Templates and click on New. Choose Add CSS file. Name it docs and add it to the existing group CSS. If we had more than one CSS file, it might be useful to create a new group at this point. 

Add the following CSS to docs.css:




#ipsLayout_mainArea {
  padding-right: 0;
}

.ipsType_sectionTitle,
.ipsWidget.ipsWidget_vertical .ipsWidget_title {
  background: #b63848;
}

/* Docs */
.cDocs {
  padding-top: 30px;
}

.cDocs h2 {
  font-size: 18px;
  font-weight: 600;
  border-bottom: 1px solid rgba(0,0,0,0.1);
  padding: 6px 10px 6px 0;
  margin-left: 10px;
  margin-bottom: 8px;
  line-height: 1.3;
}

.cDocs > li {
  padding-left: 10px;
}

.cDocs li {
  line-height: 1.6;
  padding-left: 10px;
  margin-bottom: 2px;
}

.cDocs ul ul {
  margin-left: -13px;
  padding-left: 15px;
  border-left: 1px solid rgba(0,0,0,0.075);
}
  
  .ipsJS_has .cDocs .cDocs_closed ul {
    display: none;
  }
  .ipsJS_has .cDocs .cDocs_open ul,
  .ipsJS_none .cDocs .cDocs_closed ul {
    display: block;
  }

.cDocs h3 {
  font-weight: 400;
  margin: 0;
  padding-left: 0;
  position: relative;
  cursor: pointer;
}

  .cDocs .cDocs_closed h3:before,
  .cDocs .cDocs_open h3:before {
    font-family: 'FontAwesome';
    font-size: 15px;
    position: absolute;
    left: -15px;
    top: 0;
  }
  .ipsJS_has .cDocs .cDocs_closed h3:before {
    content: '\f105';
  }
  .ipsJS_has .cDocs .cDocs_open h3:before,
  .ipsJS_none .cDocs .cDocs_closed h3:before {
    content: '\f107';
    left: -17px;
  }

a.cDocs_active {
  color: #3d6594;
  font-weight: bold;
}

/* ROWS */
.cDocs_row {
  border-bottom: 1px solid rgba(0,0,0,0.1);
  padding: 20px 0;
}

.cDocs_row .ipsType_sectionHead {
  margin-bottom: 5px;
}

#elDocs_columns .ipsPageHeader {
  margin-top: 0;
}

To include this CSS in the page for the database, go to Pages -> Page Management -> Pagein your AdminCP and open the page with the documentation for editing. Switch to the tab Page Includes tab and select CSS/Docs.css.

Include CSS into page

Click on Save and view the result in the frontend. You will notice that the categories are now collapsed so that the pages inside are no longer visible in the navigation. To add the interaction here, you have to create a JavaScript file as a last step.

Create and embed Javascript

In AdminCP go to Pages -> Page management -> Templates again and click on New. Select Add JavaScript file and enter the name docs. Use the group JS. If you need more files you can create an extra group for them to keep them separate from other files.

Open the file and add the following content:

/**
 * IPS Social Suite 4
 * (c) 2013 Invision Power Services - http://www.invisionpower.com
 *
 * ips.devDocs.js - Dev docs JS controller
 *
 * Author: Rikki Tissier
 */
;
(function($, _, undefined) {
    "use strict";

    ips.controller.register('docs.front.devDocs.main', {

        initialize: function() {
            this.on('click', '[data-action="expandSection"]', this.toggleSection);
            this.setup();
        },

        setup: function() {
            // Do we have an active item?
            var active = this.scope.find('.cDocs_active');

            if (active.length) {
                var section = active.closest('.cDocs_closed');
                section.toggleClass('cDocs_closed', false).toggleClass('cDocs_open', true);
            }
        },

        toggleSection: function(e) {
            var h3 = $(e.currentTarget);
            var li = h3.closest('li');
            var expanded = li.is('.cDocs_open');

            li.toggleClass('cDocs_open', !expanded).toggleClass('cDocs_closed', expanded);
        }
    });
}(jQuery, _));

As you can see, we use the code here already used in IPS own documentation. This is another advantage of Pages, by the way. If something doesn't work, you can get support directly from IPS and don't have to rely on the third party providers.

The last step is to embed JavaScript into the documentation page. This is done in the same way as CSS above. In AdminCP go to Pages -> Page management -> Page and open the page with the documentation for editing. Go to the tab Page Includes and click on JS/Docs.js.

Done. Now only the active category in the menu block is expanded and the others are expanded by clicking on them. 

You can see that a lot of HTML, CSS, JavaScript and some PHP was put together here. This is a simple version that you can customize, extend and develop further.

Have fun!

Link to comment
Share on other sites

 Share

×
×
  • Create New...