# Best Practices and Frequently Asked Questions

This guide covers recommendations on best practices for coding Refinery
sites, and also attempts to document answers to the most frequently asked questions.

## General

### I've never done any Ruby or Rails development. Will Refinery be easy to use for me?

The answer depends on the amount of work you are willing to put in to learn the system. If you've never done any programming, then there is an obvious challenge in learning to customize any computer system. Refinery prides itself on
doing things the 'Rails way' where possible, so any sort of customization beyond a very basic level will require some ability to code--or, at least, the ability to deductively reason.

This is a round-about way of saying that Refinery will be difficult for you, but not impossible. We're available to help on Gitter and on the mailing list, but we have limited free time. The less we have to teach you to help you achieve your goal, the more likely it is we'll be able to spend the requisite time with you, since we have to prioritize which problems get our attention. We absolutely encourage you to spend some time with Ruby and Rails; they're amazing tools, and knowing them will save you some confusion and much time.

There are number of wonderful resources to help you to learn Ruby and Rails. To name a few:

* [iwanttolearnruby](http://iwanttolearnruby.com) by [Amanda Wagener](http://awagener.com)
* [Code School](http://codeschool.com) by [Envy Labs](http://envylabs.com)

## Best Practices

### I need to make serious changes to an engine in my application. What's the best way to do that?

To be glib, the best way to make changes is not to make changes. If you want to take advantage of automatic updating, it's best not to override any models or controllers by hand. If you must add methods, do so with a decorator, which will limit your impact on the engine to whichever methods you add or override.

If you need to change how an existing method behaves, consider using a `before_action`, `alias_method_chain` or similar to get around changing the method. If you can't escape this, overwrite the method by redefining it. In the case of a controller method, you can get easy access to the code with the `refinery:uncrudify` rake task:

```shell
$ bin/rake refinery:uncrudify controller=refinery/admin/pages action=create
```

__TIP__: Running the `rake refinery:uncrudify` task outputs to `stdout`, and will not modify any files, so you can do so without fear of overwriting your existing controller modifications.

If you absolutely must modify an existing engine in large pieces, you can install the gem and unpack it to your `vendor/extensions` directory. The example below demonstrates this using the refinerycms-news extension at version 2.0.0:

```shell
gem unpack refinerycms-news --version 2.0.0 --target vendor/extensions
```

And update the relevant line in your *Gemfile* to read:

```ruby
gem 'refinerycms-news', '2.0.0', path: 'vendor/extensions/refinerycms-news-2.0.0'
```

__TIP__: For convenience, you can rename the folder of the unpacked gem to something short, like 'news', so long as you update the path specified in the Gemfile.

## Pages

### How do I add a new page part to all existing pages?

There is no facility for this. In your console, you will have to run:

```ruby
Refinery::Page.all.map do { |p| p.parts.create(:title => "My Page Part", :position => 3) }
```

If you wish to make this a default for all new pages, be sure to add it to your default parts (in 1.0.x, this is in your Settings tab; in 2.0.x, it is in the `config/initializers/refinery/pages.rb` file).

### When I go to /news or the URL of an engine, it tells me it can't find @page! What's going on?

Did you change the URL to which the page pointing to the engine redirects? If your News Page doesn't redirect to `/news`, then things will stop working. You can fortunately revert this, though, just by making your news page point there.

This is caused by the `present(@page)` statement usually found in your controllers. As long as you present a page or another model with the appropriate attributes, then you should be in the clear.

### How do I hide the page title?

[Phil](http://p.arndt.io), one of the chief maintainers of Refinery CMS, says:

> Add a `content_for :body_content_title` block in the template
> you're including from. Just make it blank and tell the
> `_content_page` partial to hide empty sections by passing it
> `:locals => {:hide_sections => [:body_content_title]}`.

## Translation

### How do I translate a 1.0.9 engine?

Please see this [gist](https://gist.github.com/3649d08ab3c84b24ab52).

## FriendlyId

### I screwed up one of the URL slugs on a site. How do I redo them?

In Refinery 2.0.x, the slug will be re-written when you resave the page.

In Refinery 1.0.x, you have have two choices. The more severe one is to reset all slugs for that model:

```shell
MODEL=news_item bin/rake friendly_id:redo_slugs
```