Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Redmine Plugin Extension and Development
Redmine Plugin Extension and Development

Redmine Plugin Extension and Development: If you'd like to customize Redmine to meet your own precise project management needs, this is the ideal guide to understanding and realizing the full potential of plugins. Full of real-world examples and clear instructions.

eBook
€8.99 €19.99
Paperback
€24.99
Subscription
Free Trial
Renews at €18.99p/m

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Table of content icon View table of contents Preview book icon Preview Book

Redmine Plugin Extension and Development

Chapter 1. Introduction to Redmine Plugins

Redmine is an open source project management platform written in Ruby and built using the Ruby on Rails framework. It currently supports a lot of key features that a software project manager would find useful, such as an issue track, wiki, time tracking, source control management integration, and various other tools that assist with document and information management.

As the product has gotten more popular, the need to extend the basic functionality through the use of third-party plugins has grown. Redmine facilitates this through a plugin API that assists in hooking external model, view, and controller code into Redmine, as well as integrating with various system features.

This chapter will introduce you to Redmine's plugin structure, as well as how to generate a new plugin, and some preliminary initialization and configuration settings. We will generate a sample plugin that we'll be using throughout this book to illustrate various code samples and topics.

The following topics will be covered in this chapter:

  • Basic plugin generation and layout

  • A brief overview of the sample plugin that will be referenced throughout this book

  • Overview of the initialization attributes

  • Introduction to some helper functions that are available to plugin authors

An introduction to our sample plugin


Throughout this book, we'll be returning to a sample plugin, a knowledgebase, to provide additional insight into a topic, or to provide code samples. The plugin we're discussing has actually been developed over a number of years, and has numerous contributors.

For the purposes of this book and any future examples, our knowledgebase is a plugin that offers a hybrid solution that lies somewhere between Redmine's wiki and document functionality.

It allows us to create articles that can be stored within categories. Categories are stored in a hierarchical fashion, so a category "tree" can be presented to users on the knowledgebase landing page, as seen in the following screenshot:

Generating a new plugin


Out of the box, Redmine provides a number of generators to facilitate the creation of plugins and plugin resources.

Note

The Redmine project website provides a plugin tutorial at http://www.redmine.org/projects/redmine/wiki/Plugin_Tutorial, which serves as a good starting point to quickly get started.

Running rails generate from the root of our Redmine installation will provide a list of available generators (truncated in the following snippet to list only those that are currently relevant):

$ rails generate
RedminePlugin:
  redmine_plugin
RedminePluginController:
  redmine_plugin_controller

RedminePluginModel:
  redmine_plugin_model

Tip

Downloading the example code

This book continually references a sample plugin known as the Redmine Knowledgebase plugin.

The source code is available on GitHub at https://github.com/alexbevi/redmine_knowledgebase and is free to view, modify, and use.

For more information on these generators, the source is available at /path/to/redmine/lib/generators. For additional information about Ruby on Rails generators, see http://guides.rubyonrails.org/generators.html.

In order to create our knowledgebase plugin, we'll first run the redmine_plugin generator, which creates the bare minimum folder structure and files we'll need to get started. This is done as follows:

$ rails generate redmine_plugin redmine_knowledgebase
  create  plugins/redmine_knowledgebase/app
  create  plugins/redmine_knowledgebase/app/controllers
  create  plugins/redmine_knowledgebase/app/helpers
  create  plugins/redmine_knowledgebase/app/models
  create  plugins/redmine_knowledgebase/app/views
  create  plugins/redmine_knowledgebase/db/migrate
  create  plugins/redmine_knowledgebase/lib/tasks
  create  plugins/redmine_knowledgebase/assets/images
  create  plugins/redmine_knowledgebase/assets/javascripts
  create  plugins/redmine_knowledgebase/assets/stylesheets
  create  plugins/redmine_knowledgebase/config/locales
  create  plugins/redmine_knowledgebase/test
  create  plugins/redmine_knowledgebase/test/fixtures
  create  plugins/redmine_knowledgebase/test/unit
  create  plugins/redmine_knowledgebase/test/functional
  create  plugins/redmine_knowledgebase/test/integration
  create  plugins/redmine_knowledgebase/README.rdoc
  create  plugins/redmine_knowledgebase/init.rb
  create  plugins/redmine_knowledgebase/config/routes.rb
  create  plugins/redmine_knowledgebase/config/locales/en.yml
  create  plugins/redmine_knowledgebase/test/test_helper.rb

As Redmine's plugin system is inspired by the Rails Engines plugin, they can also be considered as miniature applications that provide functionality to the host (Redmine) application.

Additional information regarding the Redmine plugin internals is available at http://www.redmine.org/projects/redmine/wiki/Plugin_Internals.

Note

When the plugin system was first introduced, Redmine plugins were effectively Rails Engines, but this is no longer the case (http://www.redmine.org/issues/10813).

The plugin skeleton that the Redmine plugin generator has produced includes placeholders for a number of features we'll want to include later, such as tests, initialization, documentation, MVC, database migrations, and localization.

Using custom gemsets in our plugin

As Redmine is a Ruby on Rails application, all external dependencies are managed using Bundler. This utility greatly simplifies dependency management, but by default only allows a single Gemfile to be evaluated when a bundle is being installed.

Although not provided by the default plugin generator, if our plugin will require external gemsets, we can add a Gemfile to our plugin root, which will be automatically merged by Redmine whenever Bundler commands are executed or dependencies are evaluated.

For example, we can create Gemfile in our plugin root directory as follows:

source 'https://rubygems.org'

gem 'redmine_acts_as_taggable_on', '~> 1.0'
gem 'ya2yaml'

When the Bundler installation command is run from the root of our Redmine installation, our plugin's custom gems will be included and installed:

$ bundle install
Using rake (10.1.1)
...
Using redmine_acts_as_taggable_on (1.0.0)
Using rmagick (2.13.2)
Using sqlite3 (1.3.8)
Using ya2yaml (0.31)
Using yard (0.8.7.3)
Your bundle is complete!

Generating models and controllers

The generators introduced previously include variants to generate a plugin's models and controllers.

One of the primary features of our knowledgebase plugin is the ability to manage categories. In order to implement this feature, we'll first have to generate the necessary model, migration, and controller code.

Redmine's plugin model generator parameters are the plugin name, the name of the model, then a list of attributes, and their data types:

$ rails generate redmine_plugin_model redmine_knowledgebase Category title:string description:text
  create  plugins/redmine_knowledgebase/app/models/category.rb
  create  plugins/redmine_knowledgebase/test/unit/category_test.rb
  create  plugins/redmine_knowledgebase/db/migrate/001_create_categories.rb

As we've provided some field details in our generator, the generated migration will be populated accordingly. The same process can be followed to generate the controller that coincides with our model.

Redmine's plugin controller generator follows the same pattern as the plugin model generator, but doesn't require field details:

$ rails generate redmine_plugin_controller redmine_knowledgebase Category
  create  plugins/redmine_knowledgebase/app/controllers/category_controller.rb
  create  plugins/redmine_knowledgebase/app/helpers/category_helper.rb
  create  plugins/redmine_knowledgebase/test/functional/category_controller_test.rb

Redmine's plugin views cannot be directly generated, but as they follow the standard Rails layout convention of extending ActionController and ActionView (http://guides.rubyonrails.org/layouts_and_rendering.html), we can quickly add view templates and partials to our plugin by placing the necessary files under /path/to/redmine/plugins/redmine_knowledgebase/app/views.

Note

Some of the naming conventions used by the plugin generators at the time of writing this book don't match the Ruby on Rails naming conventions. Database migrations should be prefixed with a timestamp, not an incremental value, and category_controller would become categories_controller.

The preceding examples were left intact as they reflect what the actual Redmine plugin generators produce.

Diving into the initialization file


Every Redmine plugin requires an initialization file (init.rb) to be included in order for the plugin to be registered with Redmine upon startup.

A stripped down version of the initialization file we'll be working on is included in the following snippet to highlight some of the attributes and helpers that are available:

Redmine::Plugin.register :redmine_knowledgebase do
  name        'Knowledgebase'
  author      'Alex Bevilacqua'
  author_url  'http://www.alexbevi.com'
  description 'a knowledgebase plugin for Redmine'
  url         'https://github.com/alexbevi/redmine_knowledgebase'
  version     ' 3.0.0'

  requires_redmine :version_or_higher => '2.0.0'
  
  settings :default => {
    :sort_category_tree => true,
    :show_category_totals => true,
    :summary_limit => 5,
    :disable_article_summaries => false
  }, :partial => 'settings/knowledgebase_settings'

  project_module :knowledgebase do
    permission :view_articles, {
      :knowledgebase => :index,
      :articles      => [:show, :tagged],
      :categories    => [:index, :show]
    }
    permission :create_articles, {
      :knowledgebase => :index,
      :articles      => [:show, :tagged, :new, :create, :preview],
      :categories    => [:index, :show]
    }
    # ...
  end
end

This plugin registration block contains field definitions that are used to identify the plugin to Redmine.

Note

As of Redmine 2.3.3, based on the identifier with which the plugin was registered (:redmine_knowledebase in this case), the plugin would have to reside in /path/to/redmine/plugins/redmine_knowledgebase in order to be detected properly. Note that this can be overridden using a directory attribute in future versions of Redmine, as per http://www.redmine.org/issues/13927.

Plugin attributes

The values of these fields are used to either identify the plugin to the administrator when they visit the plugin list at http://localhost:3000/admin/plugins of their Redmine deployment, or to provide some assignment or initialization functionality.

Tip

Ruby on Rails application default to port 3000 when run locally. As this is standard, we'll be using http://localhost:3000 as the base URL for all Redmine links.

The attributes that can be provided to the Redmine::Plugin.register block are as follows:

  • name: This is the full name of the plugin.

  • description: This gives a brief description of what the plugin does.

  • url: This is the website of the plugin itself. This is generally the online repository URL (GitHub, Bitbucket, Google Code, and so on), or plugin website (if available or applicable).

  • author: This holds the name(s) of the author(s) of the plugin.

  • author_url: This is generally the link to either the author(s)' e-mail addresses or blogs.

  • version: This is the internal version number of the plugin. Though not required, it is a good practice to use Semantic Versioning (see http://semver.org for more information), as Redmine follows a similar (though not official) numbering scheme.

  • settings: This field is used to define and set the default values of internal plugin settings and link to a view partial, which system administrators can use to set plugin configuration values.

    settings :default => {
        :sort_category_tree => true,
      }, :partial => 'settings/knowledgebase_settings' 

The preceding example lets our plugin know that we will be providing a configuration partial, as well as initializing a custom settings value of sort_category_tree to true.

As Redmine plugins follow the standard Ruby on Rails application hierarchy, the implied location of our settings partial would be /path/to/redmine/plugins/redmine_knowledgebase/app/views/settings/_knowledgebase_settings.html.erb.

Settings management will be covered in more detail in Chapter 7, Managing Plugin Settings.

Initialization checks

Redmine provides a number of helper functions that can be used to assist plugin authors ensuring compatibility with different versions of Redmine, as well as other plugins.

Checking for a specific Redmine version

The version or versions of Redmine that a plugin is compatible with can be specified within the plugin initialization file using the requires_redmine helper.

This helper allows the plugin author to alert Redmine system administrators that the plugin is not intended to run with the administrator's version of Redmine. Some examples of the types of version checks that can be performed are as follows:

  • Exact match

    requires_redmine "2.3.3"
    requires_redmine :version => "2.3.3"
  • Exact match of more than one version

    requires_redmine :version => ["2.2.0", "2.3.0"]
  • Match a specific version and revision

    requires_redmine "2.3"
    requires_redmine :version => "2.3"
  • Minimum version or higher

    requires_redmine :version_or_higher => "2.3.3"
  • Range of versions

    requires_redmine :version => "2.2.0".."2.3.0"
    requires_redmine :version => "2.2".."2.3"

Ensuring the existence of other plugins

Similar to the requires_redmine helper, the requires_redmine_plugin function is used to limit the successful deployment of our plugin based on the availability of another Redmine plugin.

The following examples are based on a plugin named :sample_plugin being included for availability and version checks:

  • Exact match

    requires_redmine_plugin :sample_plugin :version => "1.0.0"
    requires_redmine_plugin :sample_plugin "1.0.0"
  • Minimum version or higher

    requires_redmine_plugin :sample_plugin :version_or_higher => "1.0.0"
  • Range of versions

    requires_redmine_plugin :sample_plugin :version => ["0.1.0", "0.2.0"]

Extending core Redmine features

Now that we've initialized our plugin with some basic details and requirements, we can start integrating directly with Redmine.

A number of helper methods are available to plugin authors, which facilitate this integration with core components, such as menus and permissions.

Working with Redmine menus

The menu helper, which is also aliased to add_menu_item, allows us to inject custom entries into various content areas of Redmine. The syntax for adding a menu item is:

menu(menu, item, url, options = {})

The options hash can accept any number of the following parameters:

  • :param: This is the parameter key that will be used as the project ID (the default is :id).

  • :if: This is a proc that prevents the menu from rendering unless it is evaluated to true.

  • :caption: This is the menu caption (label), which can be a localized symbol, proc, or string.

  • :before or :after: This is used to position the menu entry relative to an existing entry. For example, :after => :activity, or :before => :issues.

  • :first or :last: If either of these options is set to true, the menu item will be placed at the absolute beginning or end of the target menu.

  • :html: This is a hash of HTML options that will be passed to the link_to instance that is used to render the menu item.

Redmine also provides a function we can use in our plugin to remove menu items, the syntax for which is:

delete_menu_item(menu, item)

The following example injects an entry into the project menu. Note that although you've added a new menu item, it may still not be available to all users due to insufficient permissions.

menu :project_menu, 
  :articles, 
  { :controller => 'articles', :action => 'index' }, 
  :caption => :knowledgebase_title, 
  :after => :activity, 
  :param => :project_id

The other valid targets for the menu are admin_menu, top_menu, account_menu, and application_menu.

The admin_menu target is used to add custom entries to the Administration menu, which is available at http://localhost:3000/admin, and can insert custom entries between the Settings and Plugins menu items.

Initializing named permissions

The permission helper is used to define a named permission for the given actions. The syntax for this helper is:

permission(name, actions, options = {})

The actions argument is a hash with controllers as keys and actions as values (a single value or an array):

  permission :destroy_contacts, { :contacts => :destroy }
  permission :view_contacts,    { :contacts => [:index, :show] }

The valid options are as follows:

  • :public: This changes the permission to public if set to true (implicitly given to any user)

  • :require: This can be set to either :loggedin or :member, and is used to further restrict the types of users the permission can be applied to

  • :read: This is set to true so that the permission is still granted on closed projects

Permissions will be covered in more detail in Chapter 3, Permissions and Security.

Project module availability

If our plugin will be adding functionality at the project level (as opposed to globally) within Redmine, we'll need to define a project_module block.

A project module is effectively a functional area within Redmine whose data belongs to a specific project, or whose scope can be limited to a project. Examples of project modules are issues, documents, wikis, or time tracking features.

Permissions defined within the project_module block will be bound to the module, as follows:

project_module :knowledgebase do
  permission :view_articles, {
    :knowledgebase => :index,
    :articles      => [:show, :tagged],
    :categories    => [:index, :show]
  }
  permission :comment_and_rate_articles, {
    :knowledgebase => :index,
    :articles      => [:show, :tagged, :rate, :comment, :add_comment],
    :categories    => [:index, :show]
  }
  # ...
end

Adding custom events to the activity stream

Activity providers are essentially models that have been defined to provide events to the activity fetcher. Once a model has registered an activity provider, activities will be mixed into a project's activity stream.

A model can provide several activity event types, which are registered by passing event types and optional class names to the activity_provider helper plugin:

  activity_provider :news
  activity_provider :scrums, :class_name => 'Meeting'
  activity_provider :issues, :class_name => ['Issue', 'Journal']

Using the activity_provider helper simply indicates that there are activity providers registered. The syntax for the helper functions is:

activity_provider(*args)

The helper simply wraps Redmine::Activity.register, which is available at /path/to/redmine/lib/redmine/activity.rb.

A matching acts_as_activity_provider entity must be initialized at the model level in order to actually utilize this functionality.

We will cover activity provider configuration in more detail in Chapter 6, Interacting with the Activity Stream.

Registering custom text formatting macros

Our knowledgebase plugin will be used to create articles, which we may want to reference in other Redmine content areas.

For example, if we want to register the kb#1 macro to link to a knowledgebase article with an ID value of 1, we would first need to register the macro with a Redmine::WikiFormatting::Macros.register block similar to the following:

Redmine::WikiFormatting::Macros.register do
  desc "Knowledge base Article link Macro, using the kb# format"
  macro :kb do |obj, args|
    args, options = extract_macro_options(args, :parent)
    raise 'One argument expected' if args.size != 1
    article = KbArticle.find(args.first)
    link_to_article(article)
  end
end

We could now include the text kb#1 in an issue, document, wiki, or anywhere else where Redmine formats text (see http://www.redmine.org/projects/redmine/wiki/RedmineTextFormatting for existing formatting options) and it would render as a link back to our knowledgebase article.

Summary


We now have a better understanding of what options are available to us when setting up a plugin for use with Redmine.

In this chapter, we covered the various plugin attributes that can be used to identify the plugin to Redmine. We also introduced some helper methods, which we'll be returning to throughout the book when we cover elements such as permissions, activity streams, and configuration in more detail.

In the next chapter, we will extend our knowledgebase plugin through the use of view hooks.

Left arrow icon Right arrow icon
Estimated delivery fee Deliver to Estonia

Premium delivery 7 - 10 business days

€25.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Mar 19, 2014
Length: 114 pages
Edition :
Language : English
ISBN-13 : 9781783288748
Languages :
Tools :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Estimated delivery fee Deliver to Estonia

Premium delivery 7 - 10 business days

€25.95
(Includes tracking information)

Product Details

Publication date : Mar 19, 2014
Length: 114 pages
Edition :
Language : English
ISBN-13 : 9781783288748
Languages :
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
€18.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
€189.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts
€264.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total 103.97
Redmine Plugin Extension and Development
€24.99
Mastering Redmine Second Edition
€41.99
Redmine Cookbook
€36.99
Total 103.97 Stars icon
Banner background image

Table of Contents

8 Chapters
Introduction to Redmine Plugins Chevron down icon Chevron up icon
Extending Redmine Using Hooks Chevron down icon Chevron up icon
Permissions and Security Chevron down icon Chevron up icon
Attaching Files to Models Chevron down icon Chevron up icon
Making Models Searchable Chevron down icon Chevron up icon
Interacting with the Activity Stream Chevron down icon Chevron up icon
Managing Plugin Settings Chevron down icon Chevron up icon
Testing Your Plugin Chevron down icon Chevron up icon

Customer reviews

Rating distribution
Full star icon Full star icon Full star icon Full star icon Half star icon 4.5
(2 Ratings)
5 star 50%
4 star 50%
3 star 0%
2 star 0%
1 star 0%
Liz and Josh Jul 23, 2014
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Quick SummaryThis book highlights the authors perspective on building a plugin from his experiences building the Knowlegebase plugin for Redmine. It covers he basics as well as some of the interesting aspects you’ll likely need like hooking into Redmine itself and working with permissions along with several other aspects you may or may not need (e.g. file attachments, integrating with the activity stream, modifying views, etc.). The end of the book wraps up with a quick overview of writing tests, although it’s more overview than something as comprehensive as the other parts of the book.Who this Book Works Well ForThis book is well written for most beginning audiences. It doesn't have extra fluff and get’s straight to the point. It’s concise almost like a cookbook, but still reads well if you like casual perusal. Basically anyone wanting to build a Redmine plugin will probably get something out of it.What This Book Isn'tThis is not a book to take a beginner to Redmine and Ruby into developing Redmine plugins without some effort. You won’t get by very easily if you don’t have a basic knowledge of Ruby and preferably of Rails. You will likely have to pull information from other sources or stumble around yourself a bit. That said it’s something manageable as the concepts and ideas underlying everything are pretty easy to figure out, and the book does seem to take you gently through the Rails aspects.If you are looking for a book in this niche of development and/or are developing a new Redmine plugin this is a great one to have at hand. It’ll save a bunch of time and effort sieving various documentation especially for some of the nuances you run into with normal plugin development.
Amazon Verified review Amazon
Eduardo Yáñez Parareda Aug 19, 2014
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
I'm the creator of SpentTime Plugin for Redmine> along other private plugins I've written for the company I work at, so I know a bit about Redmine's plugins.The book is very easy and fast to read, with a plain and direct language that tries to explain every aspect of Redmine's plugin development. The book is short,so you shouldn't expect most of it, so don't expect learning anthing about Redmine or Ruby on Rails because it isn't the goal of the book. It seems obvious butthis is not a book for novices on Ruby on Rails applications, you must know how this apps works to develop extensions for Redmine because you'll have to knowhow Redmine works as well."The good things of the book"There are several good things in this book, first of all the direct and plain language. The book is thought as a large tutorial from the beginning to the end.You could do a new plugin step by step. And it explains the most important parts of Redmine's plugins as hooks, permissions & security or how to do new modelssearchables. The explanation of hooks is the most important part of the book, very worthwhile to read.Also I like the permissions & security section and the importance the author gives to the testing side of the development. In this last section you'll findvaluables ideas about testing and continuous integration (CI) tools like Travis (CI)."The bad parts of the book2Also this book have some bad things... although not too bad. First of all it tries to explain the development of plugins using as example another plugin (KnowledgeBase),but you must refer to GitHub repository to see the code examples, so you need a browser if you want to see the code. That is not very important for all people, butI think sometimes is good to have the code in the book so you don't need to browse any page.Another missing aspect about plugins is the internazionalization. The book covers basic aspects of the development like 'Bundle' that are common to every Ruby onRails application, so treating things as internazionalization is a must too... I know it because most of the contributions to my public plugin has been translations...although it's very easy to do, it should have been covered in the book."Conclusion""Redmine Plugin Extension and Development" is a very good book for everyone that wants to write extensions for Redmine. After reading this book I planned some changeson the plugins I've wrote because I've learned very interesting things from it. You can read it in less than a week in your spare time, so it isn't a lost time.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela