Web application development References


ISO-639-1


Official languages of the United Nations

  • Arabic
  • Chinese (Mandarin)
  • English
  • French
  • Russian
  • Spanish

CLDR

Unicode Common Locale Data Repository

터미널 한글 설정

windows cmd - chcp 65001
linux shell - export LC_ALL=ko_KR.UTF-8


구글 맵스 지도 검색

https://maps.google.com/?q=이름@위도,경도

구글 정의 검색

define:something

Protocol SPDY

http://www.chromium.org/spdy

MongoDB

사용자추가 스키마생성 DB삭제

mongod 를 기동할 때는 --auth 옵션을 추가해야 함
mongoDB는 system영역 내에서 admin이라는 DB관리를 위한 스키마를 가짐
>use admin // admin DB 사용
>db.addUser('name','pswd') // 사용자 추가
>use newDB => 해당 디비가 없으면, 새로운 디비를 생성함
   mysql의 스키마 생성과 같음
>db.collectionName.drop() => 해당 collection을 삭제함
   mysql의 DROP TABLE과 같음

Mongodb eclipse

log path configuration

"C:\data\mongodb-xxxxxxxxx\bin\mongod" --service  --logpath  c:\data\test.log

import

mongoimport --host localhost --db myapp_development --collection my_collection --type csv --file C:\dev\data\test.csv --headerline --upsert

regex

mongodb regex = '^[work|accus*|planet]'
MongoDB can only use indexes on Regular Expression searches that are front (^) anchored.
RegEx searches that front-anchor and then use a wildcard query like .* will use the index for as much of the un-wildcarded area as it can before scanning --- i.e., ^foo.* will run a partial scan.


Mysql

mysql backup and restore


mysqldump -uUSER -pPASSWORD -hHOST DB > ./filename.sql
mysql -uUSER -pPASSWORD -hHOST DB < ./filename.sql

MySQL index

What should be indexed?
–All attributes where you JOIN
–All attributes where you filter (WHERE)
–All attributes where you ORDER or GROUP BY
–All attributes where you want to do an Index Scaninstead of a Table scan.
–NOT on attributes with an evenly distributed lowcardinality.
•How should be indexed?
–Indexes can only be used from left to right.
–Keep them short.
–Compound indexes: INDEX(a, b).
–Prefixed indexes: INDEX(a, b(10)).
–Do not function-cover indexed attributes

http://www.scribd.com/doc/80792061/MySQL-Performance-Tuning

MySQL Date and Time Functions


Mysql 동일 테이블에서 여러 필드 값의 합 쿼리

//쿼리1 보다 쿼리2가 두 배 이상 빠르다. 단, 하나의 칼럼 갯수를 구할 땐 where절과 count(*)를 쓰는 것이 더 빠르다.
//쿼리1
select sum(cnt) from (
    select count(*) as cnt from `my_table` WHERE `field_x` =1
    union all
    select count(*) as cnt from `my_table` WHERE `field_y` =1
    union all
    select count(*) as cnt from `my_table` WHERE `field_z` =1
) as cnt_all
//쿼리2
SELECT
(SUM(IF(`field_x` = 1,1,0)) +   
    SUM(IF(`field_y` = 1,1,0)) +
    SUM(IF(`field_z` = 1,1,0))) as cnt_all
FROM `my_table`
WHERE 1


firefox - keyword.url

http://www.google.co.kr/search?num=50&hl=ko&lr=&newwindow=1&tbo=1&as_qdr=all&aq=f&aqi=&aql=&oq=&gs_rfai=&ie=UTF-8&oe=UTF-8&sourceid=navclient&gfns=1&q=

리눅스 crontab

crontab -l

CSS FONT BASE-64

/* Fonts as files */
@font-face {
    font-family: 'MyFontFamily';
    src: url('myfont-webfont.eot?') format('eot'),
         url('myfont-webfont.woff') format('woff'),
         url('myfont-webfont.ttf')  format('truetype'),
         url('myfont-webfont.svg#svgFontName') format('svg');
    }
/* Fonts as data uris */
@font-face {
    font-family: 'MyFontFamily';
    src: url('myfont-webfont.eot?') format('embedded-opentype');
    }
   
@font-face {
    font-family: 'MyFontFamily';
         url(data:font/truetype;charset=utf-8;base64,BASE64_ENCODED_DATA_HERE)  format('truetype'),
         url(data:font/woff;charset=utf-8;base64,BASE64_ENCODED_DATA_HERE)  format('woff'),
         url('myfont-webfont.svg#svgFontName') format('svg');
    }


CSS Sticky windows

    .outer {
        width:200px;
        height:600px;
        background-color:red;
        margin:0 auto;
    }
    .inner {
        width:50px;
        border:1px solid white;
        position:fixed;
    }
 


Insert the word (image) into the alt text of an image that hasn’t loaded In Firefox

img:after   { content:" (image)"; }
img::after  { content:" (image)"; } /* New CSS3 standard notation */


FYI

References and Articles

빠른 웹 개발

도구


출처

  • 직접 작성
  • google 검색



by


Tags : , , , , , , , ,

  • 재미있게 읽으셨나요?
    광고를 클릭해주시면,
    블로그 운영에 큰 도움이 됩니다!

Ruby Gems Cheat Sheet


GEM 설정

gem environment
set GEM_PATH = D:\dev\ruby192\lib\ruby\gems\1.9.1\gems
gem update --system
gem uninstall gemname
bundle update
(vendor 폴더에 bundle 설치하기)
bundle install --path vendor/bundle


devise

Controller filters and helpers

Devise will create some helpers to use inside your controllers and views. To set up a controller with user authentication, just add this before_filter:
before_filter :authenticate_user!
To verify if a user is signed in, use the following helper:
user_signed_in?
For the current signed-in user, this helper is available:
current_user
You can access the session for this scope:
user_session
Callbacks
    after_set_user
    after_authentication
    before_failure
    before_logout
    Warden::Manager.after_authentication do |user,auth,opts|
        user.last_login = Time.now
    end
   

generator

devise g view with haml
rails g devise_views -t=haml

OmniAuth

Add :password => Devise.friendly_token[0,20] when creating a new user from facebook omniauth.

Passwords Encrypt manually


Assuming you have a mysql database with a "users" table and a "password" column And an ActiveRecord model class called "user" that is hooked up to devise
Create an ActiveRecord model class in your app app/models/old_user.rb
OldUser < ActiveRecord::Base
  set_table :users
  establish_connection :database => "old_database", :user => "old user", :adapter => "mysql"
end
then create a rake task: app/lib/tasks/migrate_users.rake
task :migrate_users => :environment do
  OldUser.find_each do |old_user|
    u = User.new(:email => old_user.email, :password => old_user.password, :password_confirmation => old_user.password);
    #if your using confirmation
    u.skip_confirmation!
    u.save!
  end
end
Modify as necessary (make sure you're saving any app-specific user attributes)
Then$ rake migrate_users
   
Good news and bad news.
Good news:
The following works to create your user's password manually.
 pepper = nil
 cost = 10
 encrypted_password = ::BCrypt::Password.create("#{password}#{pepper}", :cost => cost).to_s
You can find your pepper and cost in your devise initializer. This method was confirmed using Devise's "valid_password?" method.
Bad news:
The entire reason I was trying to avoid "User.new(password: password).encrypted_password" was because of speed. It's terribly slow. With all my other pieces of my import task, I've intentionally avoided this.
But as it turns out, the major cost here is not instantiating a User object -- but BCrypt itself. There is very little noticeable speed boost when using BCrypt directly because it's intentionally designed to be slow.
My final answer: suck it up, run the rake script, go find a beverage.

mailer locale configuration

-ActionMailer::Base.default_url_options[:locale] = I18n.locale


Simple_form

<%= simple_form_for(@user, :builder => CustomBuilder) do |f| %>
  <%= f.input :name %>
<% end %>


Client side validations

Client side validations Registering own form builder
https://github.com/bcardarella/client_side_validations/wiki/Registering-your-own-custom-form-builder


Client MVC

Spine

Important is only that the public directory of the application is specified
as domainroot in Confixx. If the domain is called Passenger will start automatically.."
rails g spine:model Card text is_private order user_id card_type
rails g spine:controller Cards
rails g spine:scaffold card text is_private order user_id card_type
rails g spine:model Organization title description url image admins members followers
rails g spine:controller Organizations
rails g spine:scaffold organization title description url image admins members followers
var card = App.Card.create({ 
  is_private: true,
  order: 0,
  card_type: 'Reason',
  text: 'Spine & Rails, sitting in a tree!'
});
straightforward way to do that without extending Spine Model's
to allow for instances to be added in memory without syncing
Ajax.disable -> saveStuff()
Model.refresh()
extends
Contact.extend(Spine.Model.Ajax);
Contact.extend({
url: '/users/'
});
'/': ->
    if AuthenticatedUser
         @controller = new OtherController
         @replace @controller.render()
    else
         @controller = new LoginController
         @replace @controller.render()
http://spinejs.com/docs/controller_patterns         
         


Compass

compass init rails D:/dev/workspace/baksisi
compass init rails -r html5-boilerplate -u html5-boilerplate --syntax sass --force
css와 javascript를 asset 폴더로 옮겨준다. rails.js는 제외 (jquery_ujs와 동일하다)


Geo_location

https://github.com/chrisyour/geo_location
http://www.maxmind.com/app/geolitecountry


Mongoid id 변경하기

http://blog.joshdzielak.com/blog/2011/12/24/tame-the-mongoid-id-field-in-your-rails-and-backbone-js-app/
http://lostechies.com/derickbailey/2011/06/17/making-mongoid-play-nice-with-backbone-js/


Mongoid Follow unfollow

class User
  include Mongoid::Document
  field :name, type: String
  has_and_belongs_to_many :following, class_name: 'User', inverse_of: :followers, autosave: true
  has_and_belongs_to_many :followers, class_name: 'User', inverse_of: :following
  def follow!(user)
    if self.id != user.id && !self.following.include?(user)
      self.following << user
    end
  end
  def unfollow!(user)
    !self.following.include?(user)
    self.following.delete(user)
  end    
end
relation_ids instead? that is self.member_count = self.member_ids.size
self.challenged.where(_id: event.id).destroy_all
def unchallenge!(announce)
  self.announcements.destroy_all( conditions: { _id: announce.id })
  self.save!
end
Finally I successfully deleted the relation using self.challenged_ids.delete(event.id)
validates_inclusion_of :foo, in: [['foo'], ['bar']]


Mongoid polymorphic behaviour

When a child embedded document can belong to more than one type of parent document, you can tell Mongoid to support this by adding the as option to the definition on the parents, and the polymorphic option on the child.
class Doctor
  include Mongoid::Document
  embeds_one :name, as: :namable
end
class Nurse
  include Mongoid::Document
  embeds_one :name, as: :namable
end
class Name
  include Mongoid::Document
  embedded_in :namable, polymorphic: true
end


TEST

Cucumber

rails g cucumber:install ?capybara ?rspec
  ruby script/rails generate cucumber:feature user email:string password:string confirm_password:string name:string nickname:string gender:integer location_name:string location:integer email_is_priavate:boolean name_is_private:boolean danted:boolean description:string
  ruby script/rails generate scaffold post title:string body:text published:boolean
  rake db:migrate
  rake cucumber


Cucumber Errors Handling

If SystemStackError: stack level too deep 
Then add gem "rspec", ">= 2.6.0.rc2", :group => [:development, :test] to Gemfile


Cucumber & Capybara Ajax

sleep second
page.driver.browser.execute_script %Q{ $('.ui-menu-item a:contains("#{link_text}")').trigger("mouseenter").click(); }
Clicking any element with Cucumber and Capybara
class Capybara::XPath
  class << self
    def element(locator)
      append("//*[normalize-space(text())=#{s(locator)}]")
    end
  end
end
When 'I click "$locator"' do |locator|
  msg = "No element found with the content of '#{locator}'"
  locate(:xpath, Capybara::XPath.element(locator), msg).click
end
The step looks for any element with the given text. Here it is in use:
Scenario: Creating an item
  Given I am signed in as "brandon@example.com"
   When I click "Add to your list"
    And I fill in "Description" with "blog about clicking any element"
    And I press enter
   Then I should see "The item was added to your list"
    And I should see "blog about clicking any element"
   


Cucumber Capybara

selenium chrome driver
https://github.com/jnicklas/capybara
http://code.google.com/p/chromium/downloads/list
http://code.google.com/p/selenium/wiki/ChromeDriver#Overriding_the_Chrome_binary_location
Capybara.register_driver :selenium_with_firebug do |app|
  Capybara::Driver::Selenium
  profile = Selenium::WebDriver::Firefox::Profile.new
  profile.add_extension(File.expand_path("features/support/firebug-1.6.0-fx.xpi"))
  Capybara::Driver::Selenium.new(app, { :browser => :firefox, :profile => profile })
end
Before("@selenium_with_firebug") do
  Capybara.current_driver = :selenium_with_firebug
end


I18n

I18n-js initialize

layout/application.html.haml
- html_tag :class => 'no-js', :lang => "#{I18n.locale}"
applcation.js
I18n.default_locale = "en"
I18n.locale = $($("html")[0]).prop("lang")
I18n.fallbacks = true


Media - Flickraw

    flickr.upload_photo(params[:photo].tempfile.path)


Gem Trouble shooting

Q. `require': no such file to load -- thin (LoadError)
A. => Add gem 'thin' to Gemfile


Rails Performance

  • Curb for Http (libcurl)
  • Yajl, the fastest JSON library.
  • excon #=> faster http
  • Nokogiri, the fastest XML library.
  • Snappy, super fast compression tool by google.
  • fast_xs
  • Memcache. (libmemcached)
  • use Ree Garbage Collector

Fastest Server

  • Unicorn
  • Thin

Profiling Tools

  • NewRelic - Monitoring Tool (Commercial)
  • Ganglia - Monitoring Tool (OpenSource)
  • Cloudflare - Performance & Security
  • rack-perftools

Rack-bug

1. Install rack-bug (branch rails3) as plugin
cd vendor/plugins
git clone -b rails3 https://github.com/brynary/rack-bug.git
If you want to you it as gem then add following line into Gemfile
gem 'rack-bug', :git => 'https://github.com/brynary/rack-bug.git', :branch => 'rails3'
2. Replace the code from file actionview_extension.rb
which is avilable in vendor/plugins/rack-bug/lib/rack/bug/panels/templates_panel/ as specified in bug of rack_bug repository
if defined?(ActionView) && defined?(ActionView::Template)
ActionView::Template.class_eval do
def render_with_rack_bug(*args, &block)
Rack::Bug::TemplatesPanel.record(virtual_path) do
render_without_rack_bug(*args, &block)
end
end
alias_method_chain :render, :rack_bug
end
end
If you are using gem override the specified file in some way
3. Add following lines into your config.ru
require 'rack/bug'
use Rack::Bug, :secret_key => "someverylongandveryhardtoguesspreferablyrandomstring"
run myapp
4. Start your server and access the URL http://your_app/__rack_bug__/bookmarklet.html
and enter the password.
http://blog.railsupgrade.com/2011/04/configure-rack-bug-for-rails-3.html


출처



by


Tags : , , , , , , ,

  • 재미있게 읽으셨나요?
    광고를 클릭해주시면,
    블로그 운영에 큰 도움이 됩니다!

Ruby on Rails Cheat Sheet


rails 데이터 타입

:string, :text, :integer, :float, :decimal, :datetime, :timestamp, :time, :date, :binary, :boolean

Rails Mimetype   

"./."                      => :all
"text/plain"               => :text
"text/html"                => :html
"application/xhtml+xml"    => :html
"text/javascript"          => :js
"application/javascript"   => :js
"application/x-javascript" => :js
"text/calendar"            => :ics  
"text/csv"                 => :csv  
"application/xml"          => :xml
"text/xml"                 => :xml
"application/x-xml"        => :xml
"text/yaml"                => :yaml
"application/x-yaml"       => :yaml
"application/rss+xml"      => :rss  
"application/atom+xml"     => :atom 
"application/json"         => :json
"text/x-json"              => :json

bundle asset precompile

bundle exec rake assets:precompile RAILS_ENV="production"
rake assets:clean< add below code if you want development environment with out precompile config.serve.static.assets = false application.rb use Bundler.require(:default, :assets, Rails.env) instead of Bundler.require(*Rails.groups(:assets => %w(development test)))

compile assets locally

Put below into development.rb
config.assets.prefix = "/temp-assets"
Also put below into application.rb
config.assets.initialize.on.precompile = false

rails logger

Rails.logger.info "My info message"
Rails.logger.debug "My debugging message"
Rails.logger.warn "My warning message"

Environment Log level

config.log_level = :debug, :info, :warn, :error, and :fatal

Validation text length CR filter

before.validation :replace.cr
  protected
  def replace.cr
    if self.description.changed?
      self.description.gsub!(/\r\n?/, "\n")
    end
  end

validation locale


// config/locales/en.yml
en:
  activerecord:
    attributes:
      user:
        email: "E-mail address"
    errors:
      models:
        user:
          attributes:
            email:
              blank: "is required"
If you are using mongoid, replace activerecord: with mongoid:

Validate associated

The answer to this turned out to be rather simple. On the parent model, you simply explicitly declare that you want the associated children validated.
parent.rb
validates_associated :children

Validate if persisted? or new_record?

validates.uniqueness.of :nickname, :message => I18n.t("user.already.taken"), :if => :new.record?
validates.uniqueness.of :nickname, :message => I18n.t("user.already_taken"), :unless => :persisted?

Session Store in rails 3

Use the database for sessions instead of the cookie-based default, which shouldn't be used to store highly confidential information
Create the session table with
rake db:sessions:create
Run the migration
rake db:migrate
Make sure you also tell rails to use ActiveRecord to manage your sessions too.
Rails 3
config/initializers/session.store.rb:
Rails.application.config.session.store :active.record.store

DB Migrate Production

rake db:migrate RAILS_ENV="production"

get rails environment

Rails.env
env["SERVER_NAME"]

rails template

rake print --silent RECIPES=jquery,haml,rspec,cucumber,guard,mongoid,action.mailer,devise,add.user,home.page,home.page.users,seed.database,users.page,css.setup,application.layout,html5,navigation,cleanup,ban.spiders,extras,git,compass,omniauth,omniauth.email,backbone > ~/Desktop/backbone.template.txt
Could you please run it again using the "-T -O -J" flags? As in
rails new template_test -m https://github.com/fortuity/rails3-application-templates/raw/master/rails3-mongoid-devise-template.rb -T -O -J
http://blog.dominicsayers.com/2011/08/16/howto-use-a-rails-template-from-github-on-windows/

thin start

D:\dev\ruby192\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) D:/dev/workspace/baksisi/script/rails server thin -b 127.0.0.1 -p 3002 -e development
ruby ./script/rails server thin -b smoke-free-online.de -p 3000 -e development -d
thin start

Middle Man

"server" was called incorrectly. Call as "middleman server [-p 4567] [-e development]".
"middleman server [-p 4567] [-e development]" instead of "middleman server -p 4567 -e development

DB migration

Rails g migration change.data.type.for.table_column

I18n

locale join

config/application.rb
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '.*', '..{rb,yml}')]

locale path

routes.rb
  match '/:locale' => "home#index"
  root :to => "home#index"
  scope "/:locale" do   
    controller :models do
      something
    end
    resources :models, :only => :show
ApplicationController
  def default.url.options(options = {})
    options.merge!({:locale => I18n.locale})
  end   

Localize

I18n.l Time.now, :format => :short,  :locale => :"ko"

Pluralization

ko:
  pears:
    zero: ko.zero
    one: ko.one
    few: ko.few
    other: ko.other

generate rake tasks

rails g task namespace task1 task2
rake -T | grep namespace

세션 저장

config.session.store :cookie.store, :key => '.baksisi.session', :domain => :all
environment.rb 메일러에 레이아웃을 지정하고 싶다면.
DeviseMailer.layout "OMG"

show routes

rake routes

SASS

config/application.rb:
config.generators.stylesheet_engine = :sass
sass-convert style.sass style.scss

Trouble Shootings

uninitialized constant

file name confirm (if file name capital, it can be occurred.)

guard-livereload error

gem install eventmachine --pre 

open-uri.rb file in C:/Ruby1.9.2/lib/ruby/1.9.1/ (of course your path might be different).

http.verify.mode = options[:ssl.verify.mode] || OpenSSL::SSL::VERIFY.NONE

[ERROR] V8 is no longer usable

ulimit -v unlimited  

CSV Data Handling

http://www.ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV.html

get action information at view

    params[:action]

HAML

rails helper using haml
 
def section(name)
haml.tag(:div, :class => 'section') do
  haml.tag(:h2, name)
  haml.tag(:p, :class => 'section.content') do
    yield
  end
end
end
      
def content.box
  haml.tag :div, :class => "holder" do
    haml.tag :div, :class => "top"
    haml.tag :div, :class => "content" do
      yield
    haml.tag :div, :class => "bottom"
  end
end
and in haml
%html
  %head
  %body
    Maybee some content here.
    - content.box do
      Content that goes in the content_box like news or stuff      
     
fields_for with index
<% @questions.each.with.index do |question,index| %>
    <% f.fields.for :questions, question do |fq| %> 
        # here you have both the 'question' object and the current 'index'
    <% end %>
<% end %>
It’s also possible to specify the instance to be used:
<%= form.for @person do |person.form| %>
...
<% @person.projects.each do |project| %>
  <% if project.active? %>
    <%= person.form.fields.for :projects, project do |project.fields| %>
      Name: <%= project.fields.text_field :name %>
    <% end %>
  <% end %>
<% end %>
<% end %>     

Rails Response

namespace "api" do
  resources :regions, :defaults => { :format => 'xml' }
end
Then you should be able to have the following work for your controller methods:
class Api::RegionsController < ApplicationController
  respond.to :xml, :json
  def index
    respond.with(@regions = Region.all)
  end
end
rescue.from  ActionController::MissingFile do |e|
  # User's browser probably wont display this
  # Content-Type is application/x-shockwave-flash
  render :file => File.join(Rails.public.path, '404.html'), :status => 404
end

show details or stream video

def show
  @media = Media.find params[:id]
  respond.to do |format|
    format.html
    format.flv { send.file @media.path, :disposition => 'inline' }
  end
end
render :file => File.join(Rails.public.path, '404.html'), :status => 404, :content.type => 'text/html'

render with variable

render :partial => "my/conejo", :locals => {:my.val => something}
render "my/liebre", :my.val => something

scope

default_scope order('id DESC')
Model.reorder('')
Model.unscoped

render an other action in the controller, in js.

  render 'result', :id => @item.id, :format => :js
 

layout xhr? 

  class ApplicationController < ActionController::Base
  layout proc{|c| c.request.xhr? ? false : "application" }
  end
  layout :layout.xhr?
  def layout.xhr?
    request.xhr? ? false : 'application'
  end
 

AJAX Performance stale? and touch


 def show
    @list_item = @list.list_items.find( params[ :id ] )
    if stale?( :etag => @list_item, :last_modified => @list_item.updated_at.utc, :public => true )
      respond_with( @list_item )
    end
  end
  Also instead of the update_list method being called from after_save/destroy you can pass :touch => true to the belongs_to association which will do the same

AJAX Handler - ?xhr

respond_with( @something, :layout => !request.xhr? )
or
respond_to do |wants|
  wants.html do
    if request.xhr?
      render :partial => "items"
    else
      render
    end
  end
end

Asset

exist

YourApp::Application.assets.find_asset("#{asset}.file").nil?

### pathname

<YourAppName>::Application.assets.find_asset('Rails.png').pathname

absolute asset_path in view using helper

"#{request.protocol}#{request.host.with.port}#{asset.path('person/gravatar.default.png')}"
"#{request.scheme}://#{request.host.with.port}#{request.script_name}"

Mailer

config

environment/production.rb
  config.action.mailer.default.url.options = {:host => 'localhost:3000',:locale =>I18n.locale}
  config.action.mailer.smtp.settings = {
    :address              => "server.addr",
    :port                 => 587,
    :domain               => "sever.domain",
    :user.name            => "user.name",
    :password             => "user.password",
    :authentication       => "plain",
    :enable.starttls.auto => true
  } 
  config.action.mailer.delivery.method = :smtp
  config.action.mailer.perform.deliveries = true
  config.action.mailer.raise.delivery.errors = false
  config.action.mailer.default :charset => "utf-8"

inline attachement

in mailer

attachments.inline['blank'] = {
    :data => File.read("#{Rails.root.to.s + '/app/assets/images/blank.png'}"),
    :mime.type => "image/png",
    :encoding => "base64"
}

in view

if @offer.image.nil?
  = image.tag( attachments['blank'].url, :id => 'attachement.image', :width => "400", :height => "400")
 

validates in I18n

%{attribute} - field name
%{model} - model name 
%{count} - count


rescue log

begin
  ...some code...
rescue Exception => e
  logger.error e.message
 

Ruby

Iterate

a.each.with.index do |item, index|
  puts item, b[index]
end
array.each.slice(3) do |elements|
  fire.the_event
end

Timezone

in client (js):
function set.time.zone.offset() {
    var current.time = new Date();
    $.cookie('time.zone', current.time.getTimezoneOffset());
}
in Application Controller:
before.filter :set.timezone
def set.timezone 
 min = request.cookies["time.zone"].to_i
 Time.zone = ActiveSupport::TimeZone[-min.minutes]
end

DateTime format

  %a - The abbreviated weekday name (Sun)
&nbsp; %A - The&nbsp; full&nbsp; weekday&nbsp; name (Sunday)
  %b - The abbreviated month name (Jan)
&nbsp; %B - The&nbsp; full&nbsp; month&nbsp; name (January)
  %c - The preferred local date and time representation
  %d - Day of the month (01..31)
  %H - Hour of the day, 24-hour clock (00..23)
  %I - Hour of the day, 12-hour clock (01..12)
  %j - Day of the year (001..366)
  %m - Month of the year (01..12)
  %M - Minute of the hour (00..59)
  %p - Meridian indicator (AM&nbsp; or&nbsp;PM)
  %S - Second of the minute (00..60)
  %U - Week  number  of the current year,
          starting with the first Sunday as the first
          day of the first week (00..53)
  %W - Week  number  of the current year,
          starting with the first Monday as the first
          day of the first week (00..53)
  %w - Day of the week (Sunday is 0, 0..6)
  %x - Preferred representation for the date alone, no time
  %X - Preferred representation for the time alone, no date
  %y - Year without a century (00..99)
  %Y - Year with century
  %Z - Time zone name
  %% - Literal ``%'' character
   t = Time.now
   t.strftime("Printed on %m/%d/%Y")   #=> "Printed on 04/09/2003"
   t.strftime("at %I:%M%p")            #=> "at 08:56AM"
  
   datetime seconds, hours, days, weeks, months, and years
  
    Add below lines to one of your initializer files, e.g., config/environment.rb:
    DateTime::DATE.FORMATS[:short]="short %Y-%m-%d %H:%M:%S"
    Time::DATE.FORMATS[:short] = "short %Y-%m-%d %H:%M:%S"
    Date::DATE.FORMATS[:short] = "short %Y-%m-%d"
    modify view:
    <%= item.create_date.to_s(:short) %>
distance_of_time_in_words(from_time, to_time = 0, include_seconds = false, options = {})
today = DateTime.now
=> #<DateTime: 441799066630193/180000000,-301/1440,2299161>
birthday = Date.new(2008, 4, 10)
=> #<Date: 4909133/2,0,2299161>
days_to_go = birthday - today
time_until = birthday - today
=> Rational(22903369807, 180000000)
time_until.to_i             # get the number of days until my birthday
=> 127
hours,minutes,seconds,frac = Date.day_fraction.to_time(time_until)
[3053, 46, 57, Rational(1057, 180000000)]
- mm  = (now-la    st_cigarette).divmod(Rational(1, 1440))[0]
- past.days = mm / 1440
- past.hours = (mm % 1440) / 60
- past_minutes = mm % 60

timezone

def set_api_time_zone
  utc_offset = current.user.session && current.user.session.user ? current.user.session.user.time.zone.offset.to.i.minutes : 0
  user.timezone = ActiveSupport::TimeZone[utc.offset]
  Time.zone = user.timezone if user.timezone
  Time.zone.today
  Time.now.to.date
    # => Thu, 19 May 2011
  Time.now.in.time.zone('Melbourne').to_date
    # => Fri, 20 May 2011
end

Range step

range.step(2) {|x| puts x}


benchmark

require 'benchmark'
n = 1000000
def answer1 current.subdomain
  case current.subdomain
  when 'www', 'blog', 'foo', 'bar'
  else nil
  end
end
def answer2 current.subdomain
  nil unless  ["www", "blog", "foo", "bar"].include?(current.subdomain)
end
Benchmark.bmbm do |b|
  b.report('answer1'){n.times{answer1('bar')}}
  b.report('answer2'){n.times{answer2('bar')}}
end
Rehearsal -------------------------------------------
answer1   0.290000   0.000000   0.290000 (  0.286367)
answer2   1.170000   0.000000   1.170000 (  1.175492)
---------------------------------- total: 1.460000sec
              user     system      total        real
answer1   0.290000   0.000000   0.290000 (  0.282610)
answer2   1.180000   0.000000   1.180000 (  1.186130)
Benchmark.bmbm do |b|
  b.report('answer1'){n.times{answer1('hello')}}
  b.report('answer2'){n.times{answer2('hello')}}
end
Rehearsal -------------------------------------------
answer1   0.250000   0.000000   0.250000 (  0.252618)
answer2   1.100000   0.000000   1.100000 (  1.091571)
---------------------------------- total: 1.350000sec
              user     system      total        real
answer1   0.250000   0.000000   0.250000 (  0.251833)
answer2   1.090000   0.000000   1.090000 (  1.090418)


출처




by


Tags : , , , , , ,

  • 재미있게 읽으셨나요?
    광고를 클릭해주시면,
    블로그 운영에 큰 도움이 됩니다!

도심 속에서 만나는 자연. 골웨이 남쪽 바닷가 산책.

바다 건너 편-'골웨이 바닷가 산책'

골웨이 남쪽의 울페톤 다리(Wolfe tone Bridge)를 지나 클라다 길(Claddagh Quay)을 따라 걸으면,
멋진 바닷가 풍경이 나타납니다.
길이 꽤 길게 이어져서 해안선을 따라 걷다 보면 시간이 훌쩍 지나지요.
이곳을 골웨이를 떠나는 날 아침에 들렀습니다.
비가 계속 많이 내렸어요.
‘아. 비 맞기 싫어.’
‘아. 걷고 싶어.’
하기 싫은 걸 피하면 불쾌한 일이 줄지만,
하고 싶은 걸 한다면 그깟 불쾌감 따위야 뭐 대수겠어요.
모자를 뒤집어쓰고 해변을 거닐기 시작했습니다.
아침마다 뜀박질하는 사람들이 비를 쫄딱 맞으며 제 옆을 스쳐 가네요.

들풀-'골웨이 바닷가 산책'

강한 바람 탓에 바닥에 몸을 누인 들풀 너머로 조용히 출렁이는 바다가 보입니다.
조금 더 걸으니 빗살이 약해졌어요.

산책 나온 개-'골웨이 바닷가 산책'

동네 사람 하나가 개를 데리고 산책을 나왔습니다.
그들은 낯선 곳을 거니는 낯선 이를 보고 잠시 발걸음을 멈추었지만,
이내 아무것도 못 본 듯이 익숙한 길을 걸어갑니다.

바닷가-'골웨이 바닷가 산책'

빗살이 다시금 거세집니다.
모자 위를 때리는 물방울 소리가 썩 듣기 좋더군요.
잠시 멈추어 바다를 바라보았습니다.
자연은 거센 비에도 우왕좌왕하지 않습니다.
아.
저도 자연에 속하는데.
왜 그처럼 의연하지 못할까요?

방파제-'골웨이 바닷가 산책'

방파제 길을 따라 걸으니 갈매기 몇 마리가 머리 위를 스쳐 갑니다.
“끼룩~ 끼루룩~”
그들의 노랫소리에 답가라도 들려주고 싶지만, 가사가 끝까지 기억나는 노래가 없네요.
흘러간 옛 노래를 조금 흥얼거리자 갈매기들이 저 멀리 떠나갑니다.
마치 자동차 엔진 소리에 놀라 달아나는 새처럼 말이에요.
제 목소리도 그리 생소한가 봅니다.
아마 그 소리가 자연스럽지 못해 그렇겠지요.



by


Tags : , , , , , , , ,

  • 재미있게 읽으셨나요?
    광고를 클릭해주시면,
    블로그 운영에 큰 도움이 됩니다!

Git cheat sheet


ssh 키페어 만들기

ssh 키 페어 만들기

git 기본 명령어


git init  - 초기화
git add * - git에 파일 목록 넣기
git commit -am 'initial commit' - 커밋
git push repository_name master - 해당 브랜치에 커밋
git clone git@app.repo.com:app/app.git - 코드를 로컬로  복제
cd app
git pull - 변경사항 풀


git 환경 설정


git config --global --list
현재 설정정보 조회할 수 있습니다. --global옵션은 전역설정에 대한 옵션이며 현재 프로젝트에만 적용할때는 주지 않습니다.
git config --global user.name "사용자명"
사용자명을 등록합니다 (필수)
git config --global user.email "이메일주소"
이메일 주소를 등록합니다. (필수)
git config --global color.ui “auto”
터미널에 표시되는 메시지에 칼라를 표시해 줍니다.



gitignore 사용하기


.gitignore
git config --global core.excludesfile ~/.gitignore_global
git rm -r --cached .
git add .
git commit -m ".gitignore 완성!"
git stash branch branchname
git fetch
git merge
git pull (git fetch + git merge branchname)


로컬 변경 무시하고 저장소에서 받아오기

모든 로컬 변경을 스태쉬 한다.
git stash save --keep-index
저장한 stash를 지운다.
git stash drop

파일 하나만 저장소에서 불러오려면 이렇게 한다.
git checkout HEAD^ path/to/file/to/revert

그리고 저장소에서 풀 한다.
git pull


특정 커밋으로 돌아가기
http://stackoverflow.com/questions/4114095/revert-to-previous-git-commit
git reset --hard 0d1d7fc32

Send a pull request on GitHub for only latest commit
http://stackoverflow.com/questions/5256021/send-a-pull-request-on-github-for-only-latest-commit
git checkout -b upstream upstream/master
git cherry-pick <SHA hash of commit>
git push origin upstream



How can I rollback a github repository to a specific commit?
http://stackoverflow.com/questions/4372435/how-can-i-rollback-a-github-repository-to-a-specific-commit
git reset --hard <old-commit-id>
git push -f



참고 자료

http://git-scm.com/
http://github.com/
아웃사이더님의 git 명령어 정리
구글 검색



by


Tags : , , , , ,

  • 재미있게 읽으셨나요?
    광고를 클릭해주시면,
    블로그 운영에 큰 도움이 됩니다!

Jquery,Coffeescript Snippet 모음


스타일 변화 시키기


    $('HTML').addClass('JS');
    * In your css */
    .JS #myDiv{display:none;}

coffee script 에서 함수 호출


    contents+="<li class='city_candidate' onclick='h(\""+data[v]+"\")'>"+v+"</li>"
    @h = h = (set) ->
      $('span#cityoutput').replaceWith("<span id='cityoutput'>"+set+"</span>")

Ajax Callback


    url = "locations"
    request = $.get url,data
    request.success (data) -> $("#regionresults").html(data)
    request.error (jqXHR, textStatus, errorThrown) -> $("#region
results").append "AJAX Error: ${textStatus}."

Slide UP


jQuery ->
  $(".search input").focus ->
    if @value == "Search"
      @value = ""
      @className = "textinput"  $(".search input").blur ->
    if @value == ""
      @value = "Search"
      @className = "placeholder"
  $('#message').css { border: '1px solid red' }
  $("p").click(function () {
      $(this).slideUp();
    });
    $("p").hover(function () {
      $(this).addClass("hilite");
    }, function () {
      $(this).removeClass("hilite");
    });

Sticky layer


sticky = () ->
  y = $(window).scrollTop()
  if y > $('#topnavigation').height()
    $('#top
navigation').css({
      'position': 'fixed',
      'top': '0',
      'z-index': "4444"
        'width': $('#top_navigation').width(), 'box-shadow': '0px 20px 20px -15px #CCC'
    })
    $('#topnavigation').removeClass("sixteen columns alpha")
    $('#main').css({'padding-top': $('#top
navigation').height()})
  else
    $('#topnavigation').removeAttr('style')
    $('#main').removeAttr('style')
    $('#top
navigation').addClass("sixteen columns alpha")
$(window).scroll(sticky)
$(window).resize(sticky)
   
   

페이드인 메시지


msg = "world"
inv = "you"
show_message = (x,y) ->
  $('span#message').hide().text(x).fadeIn(1000,
  -> $('span#message').append('!')
  )
  $('#hint').hide().text(x).fadeIn(0)$ ->
  showmessage msg,inv
    [inv, msg] = [msg, inv]
 
  $('span#message').click ->
    show
message inv,msg
    [inv, msg] = [msg, inv]
message fadein and out
.fadeIn(30).fadeOut(1000);
   

다이나믹 add remove


$('input#addlanguageskill').on 'click', () ->
  num = ($('.languageskillinnerbox').length)-1
  newNum  = new Number(num+1)
  sourceElem = $('div#language
skill' +num)
  newElem = sourceElem.clone().prop('id','language
skill'+newNum)
  newElem.find("#user
languageskillsattributes"+num+"languageid").prop({id:'userlanguageskillsattributes'+newNum+'languageid',name:'user[languageskillsattributes]['+newNum+'][languageid]'})
  newElem.append('<input onclick="remove(\''+newElem.prop('id')+'\')" id="removelanguageskill"'+newNum+' type="button" value="Remove Language"/>')
  sourceElem.after(newElem)
@remove = remove = (elemid) ->
  alert "remove : "+elem
id
  $("#"+elem_id).remove()

Nested Model Form 예제


<% formfor @person do |personform| %>  <%= personform.label :name %>
  <%= person
form.text_field :name %>
  <% personform.fieldsfor :children do |child_form| %>
    <%= childform.label :name %>
    <%= child
form.text_field :name %>
    <% unless childform.object.newrecord? %>
      <% # Don't forget to name both of these 'destroy' in Rails 3 %>
      <%= child
form.checkbox 'delete' %>
      <%= childform.label 'delete', 'Remove' %>
    <% end %>
  <% end %>
  <%= submit_tag %>
<% end %>

그리즈 몽키 ajax 콜


var jqxhr = $.ajax({
  type: "POST",
  url: trackback,
  headers: {'User-Agent': 'Trackback',
                  'Content-Type':'application/x-www-form-urlencoded; charset=utf8'},
  data: inputdata,
  datatype:"text"
   });
  jqxhr.done(function() {
    GM
log("Trackback Success : "+jqxhr.responseText);           
  });
  jqxhr.fail(function(data,statusText,error) {                
        GM_log("Trackback faild : "+statusText+" [ "+error+", "+data.responseText+" ]");              
       
       
  });
 

셀렉트 박스 정렬


sortingSelectBox(selectTagId,sortBy,order)
selectTagId <select id="selectTagId"></select>
sortBy [0:Text, 1:Value] - default:0
order[0:Ascending, 1:Descending] - default:0
Examples
sortingSelectBox("mySelectTagId",1,1) sortBy Value in Descending order
sortingSelectBox("mySelectTagId",1) sortBy Value in Ascending order
sortingSelectBox("mySelectTagId") sortBy Text in Ascending order
sortingSelectBox = (selectBoxId,sortBy,order) ->
   sortBy ?= 0
   order ?= 0
   sortVal = 0
   if order is 1 then sortVal = 2
   orderValLeft = -1 + sortVal
   orderValRight = 1 - sortVal
   selectBox = $("select#"+selectBoxId)
   options = $("select#"+selectBoxId+" option")
   selectedVal = selectBox.val()
   sortedOption = options.clone()
   options.empty().remove()
   switch sortBy
     when 0
       sortedOption.sort((left,right)->
         leftText = left.text.toLowerCase()
         rightText = right.text.toLowerCase()
         if leftText < rightText then return orderValLeft
         if leftText is rightText then return 0
         orderValRight
       )
     else
       sortedOption.sort((left,right)->
         leftVal = left.value
         rightVal = right.value
         if leftVal < rightVal then return orderValLeft
         if leftVal is rightVal then return 0
         orderValRight
       )
   selectBox.append(sortedOption)
   selectBox.val(selectedVal)
  
sortingSelectBox("country")

리다이렉트


// simulates similar behavior as an HTTP redirect
window.location.replace("http://stackoverflow.com");
// simulates similar behavior as clicking on a link
window.location.href = "http://stackoverflow.com";

JQuery 데이터 타입


dataTypeString
Default: Intelligent Guess (xml, json, script, or html)
The type of data that you're expecting back from the server. If none is specified, jQuery will try to infer it based on the MIME type of the response (an XML MIME type will yield XML, in 1.4 JSON will yield a JavaScript object, in 1.4 script will execute the script, and anything else will be returned as a string). The available types (and the result passed as the first argument to your success callback) are:    "xml": Returns a XML document that can be processed via jQuery.
    "html": Returns HTML as plain text; included script tags are evaluated when inserted in the DOM.
    "script": Evaluates the response as JavaScript and returns it as plain text. Disables caching by appending a query string parameter, "=[TIMESTAMP]", to the URL unless the cache option is set to true. Note: This will turn POSTs into GETs for remote-domain requests.
    "json": Evaluates the response as JSON and returns a JavaScript object. In jQuery 1.4 the JSON data is parsed in a strict manner; any malformed JSON is rejected and a parse error is thrown. (See json.org for more information on proper JSON formatting.)
    "jsonp": Loads in a JSON block using JSONP. Adds an extra "?callback=?" to the end of your URL to specify the callback. Disables caching by appending a query string parameter, "
=[TIMESTAMP]", to the URL unless the cache option is set to true.
    "text": A plain text string.
    multiple, space-separated values: As of jQuery 1.5, jQuery can convert a dataType from what it received in the Content-Type header to what you require. For example, if you want a text response to be treated as XML, use "text xml" for the dataType. You can also make a JSONP request, have it received as text, and interpreted by jQuery as XML: "jsonp text xml." Similarly, a shorthand string such as "jsonp xml" will first attempt to convert from jsonp to xml, and, failing that, convert from jsonp to text, and then from text to xml.
/*
If you wish to use any of the meta-characters
( such as !"#$%&'()*+,./:;?@[]^`{|}~ ) as a literal part of a name,
you must escape the character with two backslashes: . For example,
if you have an an element with id="foo.bar", you can use the selector
$("#foo.bar").
*/

Session based tokens


If you are using session based tokens, you probably generate a secure token when generating the session, and store that token in the session. When a request comes back to the server, you check that the token is included in the request and compare it to what's in the session. If it's the same token, you accept the request, if not you reject it.
To use this token with jQuery, you need to make it available to javascript. You typically do this by adding it as a javascript variable.
var csrftoken = '<%= tokenvalue %>';
Next, the trick is to bind to the global ajaxSend event, and add the token to any POST request
$("body").bind("ajaxSend", function(elm, xhr, s){
if (s.type == "POST") {
xhr.setRequestHeader('X-CSRF-Token', csrf_token);
}
});

rails-3-1-and-jquery-ui-assets 설정


# http://stackoverflow.com/questions/6133818/rails-3-1-and-jquery-ui-assets
 $ cat app/assets/javascripts/application.js
    //= require jquery
    //= require jquery-ui
    $ cat app/assets/stylesheets/application.css
    /*
     *= require vendor
     *
     */
    $ cat vendor/assets/stylesheets/vendor.css
    /*
     *= requiretree ./jqueryui
     *
     */
    vendor/assets/ $ tree
     stylesheets
         vendor.css
             jqueryui
                      jquery-ui-1.8.13.custom.css
                      ...
     images
        jquery
ui
            ui-bgflat0aaaaaa40x100.png
            ...

Finally run this command:
    vendor/assets/images $ ln -s jquery_ui/ images
   

Get center


$(document).ready(function(){
  jQuery.fn.center = function () {
      this.css("top",$(window).height()/2-this.height()/2 + "px");
      this.css("left",$(window).width()/2-this.width()/2  + "px");
      return this;
  }
  $("#container").center();
 });
 

Multiple selector

$("#txt1, #txt2, #txt3").keyup(fn);

Jquery check CKEditor


$(this).data('initialForm', $(this).serialize());
to
$(this).data('initialForm', $(this).serialize() + '&' + FieldNameOfEditor + '=' + escape(ContentsOfEditor));
And a similar change to line 4 from
if ($(this).data('initialForm') != $(this).serialize()) {
to
var formData = $(this).serialize() + '&' + FieldNameOfEditor + '=' + escape(ContentsOfEditor);
if ($(this).data('initialForm') != formData) {

Jquery Defer


(function() {
      function getScript(url,success){
        var script=document.createElement('script');
        script.src=url;
        var head=document.getElementsByTagName('head')[0],
            done=false;
        script.onload=script.onreadystatechange = function(){
          if ( !done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete') ) {
            done=true;
            success();
            script.onload = script.onreadystatechange = null;
            head.removeChild(script);
          }
        };
        head.appendChild(script);
      }
        getScript('http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js',function(){
            // YOUR CODE GOES HERE AND IS EXECUTED AFTER JQUERY LOADS
        });
    })();

Scroll to top   


var destination = $(‘#idToScrollTo’).offset().top;
$(‘html’).animate({scrollTop: destination},600);

CKEDITOR


config.toolbar = 'Modati'
config.toolbar_Modati = [['Bold', 'Italic', 'Underline','Strike', '-', 'RemoveFormat','-', 'Outdent','Indent','-','Blockquote','HorizontalRule', '-', 'JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock','-','FontSize','TextColor','BGColor']]CKEDITOR.editorConfig = function( config )
{
    config.toolbar = 'MyToolbar';
 
    config.toolbar_MyToolbar =
    [
        { name: 'document', items : [ 'NewPage','Preview' ] },
        { name: 'clipboard', items : [ 'Cut','Copy','Paste','PasteText','PasteFromWord','-','Undo','Redo' ] },
        { name: 'editing', items : [ 'Find','Replace','-','SelectAll','-','Scayt' ] },
        { name: 'insert', items : [ 'Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak'
                 ,'Iframe' ] },
                '/',
        { name: 'styles', items : [ 'Styles','Format' ] },
        { name: 'basicstyles', items : [ 'Bold','Italic','Strike','-','RemoveFormat' ] },
        { name: 'paragraph', items : [ 'NumberedList','BulletedList','-','Outdent','Indent','-','Blockquote' ] },
        { name: 'links', items : [ 'Link','Unlink','Anchor' ] },
        { name: 'tools', items : [ 'Maximize','-','About' ] }
    ];
};
config.toolbar = 'Full';
 
config.toolbarFull =
[
    { name: 'document', items : [ 'Source','-','Save','NewPage','DocProps','Preview','Print','-','Templates' ] },
    { name: 'clipboard', items : [ 'Cut','Copy','Paste','PasteText','PasteFromWord','-','Undo','Redo' ] },
    { name: 'editing', items : [ 'Find','Replace','-','SelectAll','-','SpellChecker', 'Scayt' ] },
    { name: 'forms', items : [ 'Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton',
 
         'HiddenField' ] },
    '/',
    { name: 'basicstyles', items : [ 'Bold','Italic','Underline','Strike','Subscript','Superscript','-','RemoveFormat' ] },
    { name: 'paragraph', items : [ 'NumberedList','BulletedList','-','Outdent','Indent','-','Blockquote','CreateDiv','-
 
        ','JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock','-','BidiLtr','BidiRtl' ] },
    { name: 'links', items : [ 'Link','Unlink','Anchor' ] },
    { name: 'insert', items : [ 'Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak','Iframe' ] },
    '/',
    { name: 'styles', items : [ 'Styles','Format','Font','FontSize' ] },
    { name: 'colors', items : [ 'TextColor','BGColor' ] },
    { name: 'tools', items : [ 'Maximize', 'ShowBlocks','-','About' ] }
];
 
config.toolbar
Basic =
[
    ['Bold', 'Italic', '-', 'NumberedList', 'BulletedList', '-', 'Link', 'Unlink','-','About']
];
CKEDITOR.editorConfig = function( config )
{
    config.extraPlugins = "customparagraph";
    config.toolbar = [ [ 'ThinyP' ] ]; // add other toolbars and keep in mid this can be overwritten in page which loads CKEditor
};
<script type="text/javascript">
//<![CDATA[
    // Replace the <textarea id="editor1"> with a CKEditor
    // instance, using default configuration.
    CKEDITOR.replace( 'editor1',
        {
            extraPlugins : 'customparagraph',
            toolbar :
            [
                [ 'Bold', 'Italic', '-', 'NumberedList', 'BulletedList', '-', 'Link', 'Unlink' ],
                [ 'ThinyP' ]
            ]
        });
//]]>
</script>
in the main ckeditor config-file there is an option to disable automatic <p> inserts. try to change the value of CKConfig.EnterMode and CKConfig.ShiftEnterMode for example to 'br'.
config.enterMode = CKEDITOR.ENTER_BR
lostmorethanfive, lostbeetweenfourandfive, lostbeetweenthreeandfour, lostbeetweentwoandthree, lostbeetweenoneandtwo, lostbeetweenzeroandone, gainedbeetweenzeroandone, gainedbeetweenoneandtwo,gainedbeetweentwoandthree, gainedbeetweenthreeandfour, gainedbeetweenfourandfive,gainedbeetweenfiveandsix, gainedbeetweensixandseven,gainedmorethanseven


출처




by


Tags : , , , , ,

  • 재미있게 읽으셨나요?
    광고를 클릭해주시면,
    블로그 운영에 큰 도움이 됩니다!

아란섬 이니스 모어의 깎아지른 절벽. 둔 앵구스.

전에 한 아이리시 친구한테 물었습니다.
“아일랜드에서 가장 마음에 드는 곳이 어디야?”
그 친구는 한 치의 망설임 없이 대답했어요.
“아란섬. 아! 거기 만한 곳이 없지.”
‘그렇게 멋지단 말이야?’
하긴 저는 섬을 좋아하는 편입니다.
집에서 가까운 자월도나 석모도만 해도 좋고요.
따뜻한 남쪽의 제주도는 정말 멋지잖아요?
아. 설레라.
아란섬으로 떠나는 날이에요.
그런데 날씨가 미쳤습니다.
폭풍우라니요!

돌담길-'Dún Aonghasa Inis Mór Aran Island'

물방울 필터를 쓰고 싶은 것도 아닌데,
제 마음과는 상관없이 렌즈엔 물방울 효과가 자동으로 적용됩니다.
방수 점퍼를 입고 갔는데도 튼튼한 판초 우의를 따로 빌렸어요.
비가 엄청나게 많이 왔거든요.

폭풍우를 뚫고 도착한 사람들-'Dún Aonghasa Inis Mór Aran Island'

둔 앵구스 절벽-'Dún Aonghasa Inis Mór Aran Island'

둔 엥구스 절벽은 탄성을 자아내는 곳입니다.
우와아아악!
정말 멋진 곳인데, 비가 십방에서 휘몰아칩니다.
감탄사와 비명이 함께 터져 나왔어요.
최고급 판초 우의도 다 소용없습니다.
머리 끝에서 발끝까지 홀딱 젖었어요.
지금껏 아일랜드에 지내면서 이렇게까지 무서운 날씨는 없었어요.
사진 찍다가 감전된 적은 처음입니다.
사진 찍을 때만 잠깐 꺼내 쓰고 비 맞지 않게 꽁꽁 싸매 놨는데도 그래요.
그 폭풍우에서도 살아남은 카메라가 대견하네요.

거센 바람을 맞으며-'Dún Aonghasa Inis Mór Aran Island'

이 우비 날리는 것 좀 보세요.
이 친구는 지금 영국에 산다는데, 거기서도 이런 날씨는 못 봤답니다.
거센 바람을 맞으며 절벽을 걷다가 문득 날을 참 잘 잡았단 생각이 들었습니다.
아일랜드에 맑은 날이야 한 달에 두세 번은 있지만,
이런 사람 날아갈 날씨는 지금껏 처음 겪으니까요.

둔 앵구스 절별-'Dún Aonghasa Inis Mór Aran Island'

폭풍과 절벽.
그 둘이 참 잘 어울러요.
날씨 탓인지 도로에 차도 하나 뒤집어져 있던데,
저는 좀 떨긴 했지만 어디 한 곳 부러지지도 않고 대자연을 느끼고 왔습니다.

아란섬은 참 강렬한 이미지로 남았어요.
듣던 대로 참 멋진 곳입니다.



by


Tags : , , , , , , ,

  • 재미있게 읽으셨나요?
    광고를 클릭해주시면,
    블로그 운영에 큰 도움이 됩니다!

인도의 구도자 오쇼 라즈니쉬의 가르침. 기적을 찾아서.

뭔가 겉도는 기분이었습니다.
앞으로 발걸음을 옮기지만, 뫼비우스 띠를 따라 맴도는 듯했어요.
그때 이 책이 큰 도움이 되었습니다.
그동안 가졌던 의문 중 몇이 해소되었거든요.
불교, 기독교, 힌두교, 이슬람교 등에선 정파처럼 가르친다면,
오쇼 라즈니쉬는 정사지간 같다는 느낌을 받았습니다.
사파의 시각으로도 한번 바라보고 싶은데 아직까진 기회가 없었네요.
뭐 언젠가 인연이 닿는다면 마주치겠죠.
이 책에는 오쇼 라즈니쉬의 흥미로운 관점이 잘 담겼습니다.
그렇다고 제가 그것을 덥석 믿진 않아요.
그것을 직접 겪는다면 사실이 될 테니 믿음이 필요치 않고,
경험하지 못한 것이라면 믿는다고 해도 달라질 게 없으니까요.
무지개를 한 번도 못 본 사람이 그게 하늘에 뜬다고 믿어 봤자 뭐합니까?
그것을 본 사람은 말합니다.
“비가 그치면 뜬다!”
그리고 어떤 사람들은 말합니다.
“동쪽 하늘에 뜬다.”
“아니다. 서쪽 하늘이다!”
동쪽과 서쪽은 정 반대의 방향이지만, 무지개는 어디서고 상황만 맞으면 뜹니다.
이렇게 무지개에 대한 정보를 얻었다면 우리는 밖으로 나가야 합니다.
좀 헤매면 결국 무지개를 보게 되죠.
“오! 무지개는 비가 내린 뒤에 태양을 등지고 서야 보이는군.”
스스로 깨닫지 못한다면 그것은 단지 남의 이야기일 뿐입니다.

바투 동굴-'기적을 찾아서'

오쇼 라즈니쉬의 관점과 명상 철학

얼마나 많이 달렸느냐는 것은 무의미하다. 그가 원주에 있는 한 중심과의 거리는 항상 똑같다.

불행이 시간을 길게 연장하는 반면 행복은 시간을 짧게 단축시킨다.

위험이 없는 곳으로 가지 말라. 절대 그런 곳으로는 가지 말라. 거기에는 죽음 외에 아무것도 없기 때문이다.

생각을 통제할 수 없다면 그들은 미친 사람들이다. 그리고 주인의 입장에서 자신을 다룰 수 있는 사람들만이 건강한 정상인이다.

폭력적인 사람이 비폭력주의자가 되려고 애쓴다. 화를 잘 내는 사람이 유순해 지려고 애쓴다. 거친 사람이 상냥해지려고 노력한다. 도둑이 관대해지려 하고, 사악한 사람이 성자처럼 되려고 애쓴다.
이것이 우리가 살아가는 방식이다. 우리는 있는 그대로의 우리 모습을 부정하고 항상 그 위에 무엇인가 부과하려고 애쓴다.

사하자 요가는 말한다.
“있는 그대로의 그대가 아닌 다른 존재가 되려고 하지 말라. 그대가 어떤 존재 인지를 알고 그에 충실하게 살아라. 그대가 도둑이라면, 그대가 도둑이라는 사실을 알고 그에 충실하게 살아라.”
“만약 그대가 도둑이라면 그 사실을 분명히 알아라. 도둑질을 하더라도 그 사실을 알고 하라. 내일은 도둑이 아닐 것이라는 희망을 갖고 도둑질을 하지 말라.”

영적인 삶의 길에 퇴보는 없다. 다만 진보나 정체가 있을 뿐이다.

자신이 처한 단계에서 주어지는 가르침을 신뢰하고 받아들여야 한다.

돌아서 가는 길이 더 쉽고 지름길이 가장 험난하다는 것은 수없이 증명된 바 있다.

자기 자신을 알고 깨닫는 것은 분명히 기쁜 일이다. 그러나 자기 자신을 잃어 버리는 것이야 말로 궁극적인 지복이다.

가정을 꾸려 나가면서 쓰이는 에너지를 다른 일을 위해 보존하자는 것이 출가의 이유였다.
우리가 활용하는 에너지가 매우 제한되어 있기 때문이다. 이 에너지를 다른 목적, 더 높은 목적을 위해 사용해야 한다는 것이 그 취지였다.
우리가 일상 생활에 소비하는 에너지는 아주 소량이다. 보존하고 자시고 할 것도 없다. 그리고 이 에너지를 보존하기 위해 더 많은 에너지를 소비해야 할 것이다. 에너지를 보존하기 위해서도 에너지를 소모해야 한다.
이런 종류의 산야스는 자신이 가진 빈약한 에너지를 보존하려는 인색한 사람들의 길이다. 이렇게 인색하고 옹졸한 접근 방식은 아무 소용이 없다. 여기저기에서 조금의 에너지를 저축하는데 급급해서는 안된다. 그보다도 우리 안에 잠 자는 에너지, 그 풍부하고 무한한 에너지를 일깨워야 한다.

명상가(sadhak)와 헌신자(bhakta)라는 두 가지 길이 있다. 헌신자의 신은 하늘 위에 있다. 그러므로 헌신자는 두 손을 모으고 기도하면서 기다린다. 반면, 명상가의 신은 그의 내면 깊은 곳에 잠 들어있다. 따라서 명상가는 신을 깨우려고 노력한다.

수피는 수면이라는 자연현상에 정면 공격을 가함으로써 매우 생소하고 이상한 상황을 창조한다.

날숨과 들숨의 중간 지점에 호흡이 멈춰 버린 이 순간, 완벽한 균형이 이루어진 이 순간에 삼매가 온다. 이 순간에 그대는 생명(life)이 아니라 존재(existence)를 안다.

사드구루(sadguru), 완벽한 스승에 대한 정의는 ‘구루가 되지 않는 사람’이다. 이 말은 스스로 구루라고 지칭하는 사람들은 구루가 될 자격이 없음을 뜻한다.

이해의 차원에 도달한 사람들은 인간이 꿈꾸는 두 가지 목표에 대해 말한다.
섹스와 해탈이 그것이다. 부와 종교라는 다른 두 가지 목적은 단지 수단에 불과하다. 부는 섹스를 위한 수단이다. 그러므로 성적인 시대일수록 부를 지향하며, 해탈을 구하는 시대일수록 종교를 지향한다. 부가 수단이듯이 종교 또한 수단에 지나지 않는다.

어제로 돌아가기를 원한다면 그대는 눈을 감고 어제를 떠올릴 수 있다. 그러나 그런 상태가 얼마나 가겠는가? 눈을 뜨는 순간 그대는 현재에 있는 자신을 발견할 것이다.

일시적인 행복은 동물적인 차원에서도 가능하지만 영원한 행복은 신과 하나가 되었을 때 만 가능하다.

타인이라는 현상 자체가 환상이다. 일단 이것을 깨달으면 삶이 아주 단순해진다. 타인을 지향하는 모든 행동이 중단된다. 이 때는 타인을 위해 어떤 일을 하건, 그대 자신을 위해 어떤 일을 하건 오직 그대만 남는다. 그대는 타인을 도와 줄 때도 그를 타인으로 간주하지 않으며, 타인으로부터 도움을 받을 때도 그를 타인으로 간주하지 않는다.

사실 착취(exploitation)와 실용화(utilization) 사이에는 엄청난 차이가 있다. 내가 나의 에고를 위해 무엇인가 이용한다면 그것은 착취다. 그러나 재가 온 세상을 위해, 모든 사람을 위해 어떤 것을 이용한다면 거기에 착취의 문제는 없다.

구루를 찾는다면 그대는 그 자리에 정체될 것이다. 이정표 위에 멈춰 서지 말라.

실제로, 마음은 어디로 갈지 갈피를 잡지 못한다. 마음은 천국으로 가야 행복할지 지옥으로 가야 행복할지 결정하지 못한다. 항상 두려워한다. 이렇게 두 발을 각기 다른 배에 올려놓으면 아무데로도 가지 못한다. 그대는 물에 빠져 죽고 말 것이다.

쿤달리니가 각성된 후에는 폭력적인 성향이 완벽하게 사라진다. 폭력을 행사하지 않을 뿐만 아니라 내면의 폭력성도 사라진다. 폭력을 행사하고 싶은 충동, 남에게 해를 입히고 싶은 충동은 쿤달리니가 잠자고 있는 상태에서만 가능하다. 쿤달리니가 깨어나는 순간 타인은 더 이상 타인이 아니다. 그러므로 타인에게 해를 입히려는 충동은 불가능하다. 이 때는 폭력적인 충동을 억누를 필요가 없다. 그런 충동 자체가 없으므로 폭력적으로 되는 것이 불가능하다.
만일 폭력적인 충동을 억눌러야 한다면 쿤달리니가 아직 깨어나지 않은 것이다. 그렇게 알면 된다. 눈을 뜬 다음에도 여전히 지팡이가 필요하다면 그대의 눈은 아직 사물을 보지 못하는 것이다.

인간의 일곱가지 신체

객관적 평가 가능한 영역

  • 첫 번째 - 물질적 육체 - 육체만이 형성
  • 두 번째 - 에텔체(etheric body) - 감정의 성장
  • 세 번째 - 아스트랄체(astral body) - 이성과 사유, 지성

주관적인 영역

  • 네 번째 - 멘탈체 (metal body) 또는 심령체(physic body)
  • 다섯 번째 - 영체(spiritual body)
  • 여섯 번째 - 코스믹체 (cosmic body)
  • 일곱 번째 - 니르바나 사리르 (nirvana sharir), 열반체 (nirvanic body), 무체의 체(bodiless body)

다섯번째 신체에서 모크샤(moksha)가 경험된다. 그 전에 있는 네가지 신체의 한계가 무너지고 영혼이 완전히 자유롭게 된다. 그러므로 해탈은 다섯 번째 신체의 경험이다. 천국과 지옥은 네 번째 신체의 차원에 속한다. 이 차원에 정체된 사람은 천국과 지옥을 경험할 것이다. 첫 번째나 두 번째, 또는 세 번째 신체에 머무는 사람들에게는 탄생과 죽음 사이의 삶이 전부다 그들에게는 죽음 너머의 삶이 존재하지 않는다.

모든 남자는 내부에 여성체를 갖고 있으며, 모든 여자는 내부에 남성체를 갖고 있다.
그러므로 우연히 어떤 여자가 자신의 남성체와 일치하는 남자를 배우자로 얻거나, 어떤 남자가 자신이 여성체와 일치하는 여자를 배우자로 얻는다면 그야말로 성공적인 결혼이다.

구도자는 안전을 경계해야 한다. 구도자에게는 안전에 대한 욕망이 가장 큰 집착이다. 한순간이라도 안전을 추구한다면 그는 이미 길을 잃어버린 것이다.
구도자는 항상 ‘나는 안전을 구하고 있지 않다.’는 것을 마음에 새겨야 한다. 그대는 안전이 아니라 진리를 구하는 것이다.

속박이 있는 곳에 관계는 없다. 그리고 관계가 있는 곳에서 속박은 불가능하다.

눈먼 사람은 등잔이나 전깃불을 만나도, 밝은 태양 아래에 나서도 결코 빛을 보지 못할 것이다.

탐구(seek)하는 것과 요구(ask)하는 것은 다른 일이다. 실제로, 탐구를 원하지 않는 사람만이 요구한다.

에고와 ‘나의 존재성’이 어떻게 다른지 이해해야 한다. 에고, 즉 ‘나(I)’라는 느낌은 죽겠지만 ‘존재(am)’라는 느낌은 죽지 않을 것이다. ‘I am’ 안에는 두 가지가 있다. ‘I’는 에고고 ‘am’은 아스미타(asmita), 존재의 느낌이다.

전세계에 만연한 남녀간의 불평등은 남자가 자신을 ‘주는 자’로 생각하고 여성은 자신을 ‘받는 자’로 생각한다는 사실에서 비롯되었다. 받는 쪽은 왜 반드시 열등해야 하는가? 누가 그렇게 말하던가? 받는 자가 없다면 주는 자가 무슨 소용인가? 그 반대의 경우도 성립된다. 주는 자가 없다면 받는 자가 무슨 소용인가? 이것은 열등함과 우월함의 문제가 아니다. 둘이 서로 보완적인 위치에 있다.

우리는 항상 값을 치를 준비를 해야 한다. 실제로 값을 치를 준비가 되어 있을수록 우리는 더 가치 있는 것을 얻는다.

동물에게는 내일이 없다. 그들에게는 오늘이 전부다. 어떤 면에서는 오늘조차 없다. 내일이 없는 그들에게 오늘이 무슨 의미가 있겠는가?

행복은 지겨움을 낳는다. 행복만큼 권태를 불러 오는 것은 없다. 불행은 지겹지 않다. 불행한 마음은 결코 권태롭지 않다.

성교에는 두 종류가 있다. 하나는 단순히 음식을 먹는 것이고, 다른 하나는 음식을 소화시키는 것이다. 우리가 흔히 알고 있는 성교는 음식을 먹고 토하는 행위에 불과 하다. 아무것도 소화되지 않는다. 무엇인가 소화되면 그 만족감은 훨씬 더 깊어지고 오래간다. 그러나 소화 흡수 작용은 에너지의 순환이 형성되었을 때만 가능하다.

가정을 가진 사람에게는 섹스가 많은 문제 중 하나에 불과하다. 그러나 전통적인 산야신에게는 섹스가 유일한 고민거리다.

사념(thought)과 사유(thinking)사이에는 차이점이 있다. 사념은 자동적인 현상이다. 사념은 항상 이방인처럼 왔다가 떠난다. 사념은 항상 이방인이라고 말하는 것이 옳은 표현이다. 그러나 사유는 우리의 것이다. 이 사유는 다섯 번째 신체에서 시작될 것이다. 이 때 그대는 단순히 다른 사람들의 사념을 수집하는 것이 아니라 그대 스스로 사유하게 될 것이다.

하나의 차원 안에서 삼매가 일어난다면 그것은 가짜 삼매다. 진짜 삼매는 차원들 사이에서 일어난다. 그것은 하나의 문일 뿐이지, 방안에 존재하지 않는다. 그것은 방밖에 있어야 한다. 다음 방과 연결되는 지점에 있어야 한다.



by


Tags : , , ,

  • 재미있게 읽으셨나요?
    광고를 클릭해주시면,
    블로그 운영에 큰 도움이 됩니다!

아일랜드에서 스윙 추기 가장 좋은 동네. 골웨이로 린디합 출빠 하세요.

아일랜드에서 지낸 지 어느덧 십 개월이 흘렀습니다.
한 번 정도는 살아볼 만한 곳이지만,
다시 이곳에서 한 해를 보낼 일은 없을 것 같은 나라라고 생각했죠.
‘언제 또 여기 발을 디딜지 모르니 골웨이나 한번 놀러 가자.’
별 기대 없이 갔던 서부의 작은 도시.
그곳에 도착했을 때 날씨는 아일랜드에 살던 중 최악이었지요.

massimo-'Swing dance Galway'

이틀 동안 출빠를 하곤 아일랜드에 대한 생각이 바뀌었습니다.
‘내가 만약 춤에 제대로 빠진다면, 골웨이에 와서 일 년을 사는 것도 괜찮겠다.’
더블린이나 코크보다 스윙 댄서가 유달리 많은 건 아닙니다.
춤추는 사람 수는 거기서 거기에요.
얼마 안 되죠.

live band-'Swing dance Galway'

춤추는 환경이 좋은 거냐 하면 그도 아니지요.
첫날 출빠한 곳은 춤 판 한복판에 기둥이 떡 하니 서 있습니다.
가볍게 스윙 아웃 하다가 기둥을 깜빡해서, 팔로워 백본 브레이커가 될 뻔 했어요.
그럼 골웨이에서 무엇이 그리 마음에 드느냐고요?

live band-'Swing dance Galway'

춤추는 분위기가 참 편안하고 좋았습니다.
출빠를 할 땐 보통 ‘춤을 추러’ 가잖아요?
그런데 여기서 출빠할 땐 ‘춤도 출겸’ 갔습니다.

라이브 공연과 춤-'Swing dance Galway'

그냥 굳이 춤 안 추고 남들 추는 거만 봐도 재미나고 그랬어요.
게다가 이틀 연속 라이브 공연에 춤을 춘 지라 더욱이 마음에 들었나 봅니다.
제가 만약 린디합 마니아라면.
이곳을 베이스캠프로 일 년 내내 유럽 스윙 페스티벌을 다니며 지내고 싶네요.:D


골웨이 스윙 이벤트 정보



by


Tags : , , , , , , , , ,

  • 재미있게 읽으셨나요?
    광고를 클릭해주시면,
    블로그 운영에 큰 도움이 됩니다!

부드러운 아이리시 위스키. 제임슨.

술병-'Jameson'

동네 슈퍼마켓에 가면 주류 판매대에 대표 아일랜드를 대표하는 위스키가 진열되어 있습니다.
부쉬밀(Bushmill), 패디 (Paddy), 파워 (Power) 그리고 제임슨(Jameson).
이렇게 네 제품이 눈에 띄는데요.
아이리시 위스키는 세 번 증류하여 맛이 깔끔합니다.
부쉬밀과 패디는 맛봤고 이번이 세 병째 위스키군요.
술을 고르기 전에 고민이 좀 되었습니다.
칵테일이나 가끔 만들어 마시니 한 병사면 오래가거든요.
아마도 둘 중 한 병은 아일랜드를 떠나기 전에 맛보지 못할듯합니다.
'파워? 아일랜드의 힘인데?!'
결국 이름이 친근한 제임슨을 집어 들고 나왔어요.
맛을 보니 탁월한 선택이었습니다.
부쉬밀은 깊은 맛이 인상적이라면,
제임슨은 부드러운 맛이 일품이랄까요?
스트레이트로 마시기에 참 좋아요.
그러나 전 주로 칵테일을 만들어 마십니다.
겨울에 춥고 비가 많이 와서 여름이 오면 좀 날이 풀리려나 했는데,
여름이 되니 폭풍우가 몰아칩니다.
난방하기엔 뭐하지만, 가만히 앉아있으면 쌀쌀한 날씨에요.
이런 날씨에 마시기 좋은 칵테일입니다.
이름하야 아이리시 헤일스톰!
그 제조법을 적어 볼게요.

칵테일 아이리시 헤일스톰 비방


재료
  • 카카오 100% - 3TS
  • 커피 - 1TS
  • 뜨거운 물 - 60ml
  • 아이리시 위스키(제임슨이나 부쉬밀) - 50 ml
  • 베일리스 - 25 ml

만드는 법
우선 카카오와 커피에 뜨거운 물을 부어 잘 젓습니다.
삼 분 후에 아이리시 위스키를 부어주세요.
세상의 모든 애주가가 행복하길 바라는 마음을 담아 잘 흔들어 줍니다.
그럼 시커먼 액체가 위스키를 집어삼켜요.
그리곤 베일리스를 얹어주면 끝!

간단하죠?
폭풍우가 몰아치는 밤에 마시기 좋은 달콤쌉싸름한 칵테일이에요.



by


Tags : , , , , , , , ,

  • 재미있게 읽으셨나요?
    광고를 클릭해주시면,
    블로그 운영에 큰 도움이 됩니다!

스페인 카미노 데 산티아고 도보 여행 안내서. 은의 길 (욕하지 말고) 웃으며 걸으세요.

은의 길 (욕하지 말고) 웃으며 걸으세요.

제목이 좀 깁니다.
하지만 유쾌한 이 책의 성격을 잘 나타내 준다고 생각해요.
‘스페인의 도보 여행길. 비아델라플라타를 완벽하게 파헤친다! 상세 지도와 현지 정보 전격 수록.’
이런 제목이 붙었다면, 지도 코너나, 덩치 좋은 가이드북 사이에 파묻히지 않았겠어요?
정보로 꽉 찬 안내 책자는 왠지 교과서를 읽는듯하여 머리가 아픕니다.
간혹 서점에 가더라도 가이드북 코너는 잽싸게 지나치는 편이죠.
그래도 가끔은 안내서를 뒤적이게 될 일이 생깁니다.
새로운 마을에 도착하여 동네 지도를 구하지 못했을 때에요.
물론 지나가는 사람에게 물어보면 되지만,
날씨가 궂거나 사람이 잘 지나다니지 않는다면 그러기 어렵습니다.
그럴 때 마을 지도 한 장이 참 큰 도움이 돼요.
‘은의 길 (욕하지 말고) 웃으며 걸으세요’엔 마을 약도가 잘 나온 편입니다.
숙소나 슈퍼 정보도 간략히 소개해 두었어요.
도보 여행안내서인 만큼 코스 공략도 되어 있지만,
보통의 안내서처럼 자세한 설명이 된 건 아닙니다.

코스 시작 지점에서 전방으로 백 미터를 걷고, 그다음엔 오른쪽 45도 각도로 꺾습니다.
직진으로 이백칠십 미터를 간 후, 아홉 시 방향의 길로 들어섭니다.
다시 사백 미터를 전진하면 과속 단속 카메라가 있으니 시속 이 킬로미터로 서행하세요.

이런 식으로 처음부터 도착지까지 길을 안내해 두었다면,
네비게이션을 보고 가는 것과 별다르지 않겠죠.
그러면 길을 걷는 내내 책을 들여다봐야 하니,
도보 여행의 재미를 느끼기 어렵습니다.
걷다가 책을 꺼내 볼 일이 없는 게 가장 좋다고 봐요.
하지만 도저히 길을 찾기 어려울 땐 먼저 간 여행자가 남기고 간 표식이 도움됩니다.
“이 갈림길에서 왼쪽 길로 가시면 마을입니다. 오른쪽 길로 갔더니 막다른 골목이더라고요.”
딱 이 정도만 귀띔합니다.
그럼 책의 나머지 부분은?
글쓴이가 길을 걸으며 겪은 그날그날의 일화가 담겼어요.
여행기 + 안내서라고 보면 되겠네요.
꼭 은의 길을 가지 않더라도 재미로 읽기 좋은 책입니다.
읽다가 한 번 정도는 웃으실 거에요. :D
앞으로도 이처럼 독특하고 술술 읽히는 여행 안내서가 책방에 모습을 드러내길 바랍니다.



리오네그로델푸엔테 가는 길 - 죽여주는 댐(God dam)

이미 틀이 잡힌 분야의 관례를 뒤집는 건 위험이 큽니다.
그럼에도 이 안내서를 출판하는 모험을 감행하신 푸른길 출판사의 김선기 대표님.
책이 나올 때까지 꼼꼼히 신경 써주신 편집자 이유정님.
고맙습니다.




by


Tags : , , , , , , , , , , ,

  • 재미있게 읽으셨나요?
    광고를 클릭해주시면,
    블로그 운영에 큰 도움이 됩니다!

동화속으로의 여행. 골웨이 코네마라. 킬모어 수도원.

골웨이에서 서북쪽으로 80Km 정도 달려가면 킬모어 수도원이 나옵니다.
교통편이 마땅치 않아 여행사를 통해 다녀왔어요.
여행사를 이용하면 왠지 정신이 없을듯하지만,
코네마라 투어는 킬모어 수도원 왕복 교통편 정도입니다.
중간마다 잠시 내려 쉬어가긴 하지만 특별히 시간에 쫓기지 않아요.
주 목적지인 킬모어 수도원도 두 시간 반 동안 충분히 돌아봤거든요.

입구-'Kylemore Abbey Connemara'

차에서 내리면 입구부터 감탄사가 나옵니다.
“이야~~ 멋진데.”
호수를 끼고 서 있는 이 성에서라면 오랜 세월을 보내도 지루할 턱이 없겠습니다.

호수-'Kylemore Abbey Connemara'

그리고 성 쪽으로 걸어가 호수를 바라보았어요.
아. 자연의 신비란!
호숫가에 비친 산과 나무를 보니 신나서 펄쩍 뛰고 싶군요.
전에 아이리쉬 댄스를 보았을 때 우스울 정도로 너무 촐랑댄다 싶었는데,
이곳에 와보니 그 모습이 이해됩니다.
이런 곳을 보고 어찌 기쁘지 않겠어요.

거울-'Kylemore Abbey Connemara'

산책로를 따라 거닐다 보니 웬 거울이 서 있습니다.
“뭐야 쌩뚱 맞게 웬 거울이지?”
사실 이건 다른 세계로 통하는 차원 문 입니다.
이런 곳에 서있는 거울이 평범할 리가 없잖아요?
보름달이 뜨는 날 밤 자정에 이 거울로 손을 뻗으면 다른 차원으로 이동합니다.

정원-'Kylemore Abbey Connemara'

사람이 잘 가꾼 정원도 하나 보입니다.
이 정원을 먼저 보고 다른 곳을 걸을 걸 그랬다는 아쉬움이 들더군요.
저는 아무래도 자연이 가꾼 정원이 더 마음에 드니까요.



by


Tags : , , , , , ,

  • 재미있게 읽으셨나요?
    광고를 클릭해주시면,
    블로그 운영에 큰 도움이 됩니다!

태국·중국·유럽 음식을 한 곳에서! 코크 에덴 레스토랑.

입구-'Eden Restaurant Cork'

에덴 음식점은 엄청난 가짓수의 메뉴를 자랑하는 음식점입니다.

메뉴-'Eden Restaurant Cork'

태국과 중국 요리가 주를 이루고, 행여나 아시아 음식이 입맛에 안 맞는 손님을 위한 유럽피언 메뉴도 갖추어 놓았죠.
음식 맛이 특별히 뛰어난 곳은 아니지만,
위치가 좋아요.
시내 한복판에 자리를 잡았거든요.
선호하는 음식이 다른 사람들끼리 모인다면, 약속 장소로 딱입니다.

새우 튀김-'Eden Restaurant Cork'

어묵 튀김-'Eden Restaurant Cork'

전체요리인 새우튀김·어묵이 꽤 바삭하고 맛이 좋습니다.

오리 요리-'Eden Restaurant Cork'

오리 요리-'Eden Restaurant Cork'

주요리로 먹은 태국식 오리 요리도 맛이 괜찮았어요.
이날 왠지 기름진 음식이 땡겨서,
기름진 튀김에 기름 좔좔 흐르는 오리 요리를 코코넛 밥에 얹어 먹었더니 좀 느끼했습니다.
전체와 주 요리 중 하나는 스프링롤처럼 좀 깔끔한 걸 시킬 걸 그랬어요.
배가 그리 고프지 않았는지, 음식량이 많은 건지 밥을 반공기도 안 먹었는데 배가 찼습니다.
밥그릇이 좀 크긴 해요.
생긴 건 밥그릇인데 크기는 대접이거든요.
배를 든든히 채우고, 간단한 후식으로 마무리합니다.

베일리스 케이크-'Eden Restaurant Cork'

베일리스 케이크에요!
이렇게 먹고 나면, 배에 기름이 좔좔 흐릅니다.^^;

에덴 레스토랑 위치



by


Tags : , , , , ,

  • 재미있게 읽으셨나요?
    광고를 클릭해주시면,
    블로그 운영에 큰 도움이 됩니다!

아일랜드의 몽마르뜨. 타이타닉이 마지막으로 들렀던 항구 마을. 코브.

코브엔 관광객의 발걸음이 끊이지 않습니다.
타이타닉의 마지막 기항지로 널리 알려졌기 때문인데요.
그래서인지 마을을 돌아다니면서 ‘타이타닉’이란 글씨가 심심치 않게 보입니다.

Heritage Center-'Cobh'

기차역 부근에 상점과 박물관이 몰려있는데요.
사람들은 주로 그 주변에서 시간을 보내다가 집으로 돌아갑니다.
그럼 코브는 타이타닉이 유명한 관광지라는 기억으로만 남을 테지요.
그건 참 아쉬운 일입니다.
언덕을 올라가면 코브의 소박한 풍경이 한눈에 들어 오거든요.

성당-'Cobh'

가장 경치 좋은 곳엔 신고딕 양식(?)으로 지어진 성당이 서 있어요.
이 성당 앞마당에서 코브를 내려다보면 마치 파리의 몽마르뜨에 온 듯 합니다.
저는 이곳이 마음에 들어요.
몽마르뜨는 워낙 유명한 장소라 사람으로 붐비지만,
코브의 언덕배기엔 그리 많은 사람이 올라오진 않거든요.

오래된 집-'Cobh'

마을을 내려다보니 오랜 세월 한 자리에 서 있던 집들이 보입니다.
요즘 지어지는 집과 별다른 점이 없어 보이죠?
잘 보면 집마다 굴뚝이 여러 개입니다.
코크에도 이런 집들이 좀 되지만 무심코 지나쳤었는데,
여기선 그것이 유난히 눈에 띄어 오랫동안 바라봤어요.
굴뚝이 네 개인 곳도 보이고, 여덟 개씩이나 되는 집도 있죠.
중앙난방이 안되던 시절엔, 방마다 벽난로가 있었답니다.
그래서 방 개수만큼 굴뚝이 필요하던 거죠.
겨울이면 방마다 먼지 날리고 청소하기 참 어려웠겠어요.
우리나라 선조의 지혜에 다시 한번 감탄했습니다.
지리산 칠불사(七佛寺)의 아자방(亞字房)은 한번 불을 지피면 49일이나 따뜻했다는 이야기도 있잖아요. :D

벽화-'Cobh'

코브 구경을 마치고 기차역으로 돌아가는 길에 커다란 벽화가 보입니다.
타이타닉이 침몰한 지 100년이 흘렀다네요.
내년엔 이곳에 101주년을 알리는 벽화가 그려지겠지요.



by


Tags : , , , ,

  • 재미있게 읽으셨나요?
    광고를 클릭해주시면,
    블로그 운영에 큰 도움이 됩니다!

따듯한 가족 영화. 무협.

반통랑-'武俠, Wu Xia'

제목만 보면 액션으로 가득한 영화일 듯합니다.
그러나 막상 액션은 얼마 나오지 않아요.
사람 사이의 갈등을 주제로 다룬 드라마거든요.
주인공인 리우진시는 아버지와의 갈등으로 집을 박차고 나왔습니다.
그리곤 시골 마을에서 한 여자를 만나 살림을 차렸죠.
그 여자의 전남편은 “저녁때 보자.”라는 말을 남기고 나가선 몇 년간 돌아오지 않았습니다.
그래서 리우진시 마저 떠날까 봐 항상 불안해합니다.
어느 날 그 둘이 사는 조용한 마을에 불량배 둘이 들이닥칩니다.
리우진시는 둘을 때려눕히고,
그 사건 때문에 쉬바이쥐가 조사를 하러 마을에 들어오죠.
의협심과 책임감으로 똘똘 뭉친 완벽주의자.
온몸이 긴장으로 가득한 채 사는 그를 보며 참 안타까웠습니다.
도대체 왜 그리 인생을 피곤하게 사느냐, 가서 멱살이라도 한번 잡고 싶더군요.
부담스러울 정도로 일을 벌여 놓고,
그 때문에 밤잠을 설치는 모습이 왠지 제 모습과 겹쳐 보인 탓에 그랬을지도 모릅니다.
쉬바이쥐는 아내와의 갈등이 있어요.
장인이 가짜 약을 파는 걸 알고 법의 심판을 받으라고 말을 했는데,
그 말을 듣고 자살했습니다.
마이클 샌델 교수의 ‘정의란 무엇인가?’가 불현듯 생각나더군요.
정의라든가 법이라든가 하는 건 생각할수록 골치가 아픕니다.
세상 사람 모두가 양심을 외면하지 않고 산다면, 법이나 정의에 대해 알 필요도 없겠죠.
그런 이상적인 세상이 오는 걸 제가 죽기 전에 보게 될까요? :D

리우진시의 아버지는 아주 권위적인 사람입니다.
그리고 자식이 가업을 이어가길 원해요.
가업은 사람 죽이는 일입니다.
그게 싫어서 숨어 지냈는데 들키고 말았어요.
문제가 생겼을 때 해결을 하지 않는다면 결국 계속 따라다닙니다.
그러니 피하고 싶어도 마주 보고 담판을 지어야 해요.
리우 진시가 도망가고 싶었던 문제는 해결이 쉽지 않습니다.
다른 사람을 죽이고 싶지 않다면, 아버지를 죽여야 하거든요.
살인마가 되거나 아버지를 죽이는 패륜을 저질러야 하는 상황.
외통수죠.
저를 낳아주신 부모님께서 얼마나 고마우신 분들인지 다시 한번 느꼈습니다.
한 번도 저에게 사람을 죽이란 명령을 내린 적이 없으니까요. :D



by


Tags : , , , , , ,

  • 재미있게 읽으셨나요?
    광고를 클릭해주시면,
    블로그 운영에 큰 도움이 됩니다!

코크와 가까운 포타 동물원에서 야생을 만나세요.

한국에서는 과천의 동물원을 종종 가곤 했는데,
언제 마지막으로 들렀는지 기억이 가물가물 하네요.
오랜만에 동물원을 찾았습니다.
코크에서 전철 타고 세 정거장만 가면 동물원 앞에 바로 내려주지요.
역 주변에 쳐진 울타리엔 얼룩말 무늬를 그려 놓았습니다.
표를 사고 들어가니 일반 공원과 별다름이 없는 모습이에요.
맹수를 제외하곤 철망 안에 가두어 두지 않기 때문이죠.

Lemur-'Fota wildlife park'

여우원숭이가 사는 집 근처엔 나무로 울타리가 쳐져 있습니다.
‘먹이를 주거나, 너무 가까이 다가가지 마세요.’
라는 안내 표지판이 되어있더라고요.
울타리 안에서 여우원숭이가 모여 지내는 게 보입니다.
‘신기하군. 나가고 싶으면 언제라도 나가도 되겠는데, 안 나가네?’
생각하기가 무섭게 여우원숭이 한 마리가 울타리 위로 훌쩍 점프합니다.
잠시 저와 눈을 마주하고 미소지은 녀석은, 보란 듯이 울타리 밖으로 뛰어나갑니다.
마침 근처에 계시던 사육사 한 분이 여우원숭이의 습성을 설명해주었어요.
밥은 자기 집에서만 먹는답니다.
나가 놀다 가도 배고프면 돌아온대요.

Monkeys-'Fota wildlife park'

이 동물원엔 유난히 원숭이 종류가 많습니다.
원숭이 공원이라고 불러도 될 정도예요.
너구리 꼬리 원숭이, 패션 리더 원숭이, 멍한 표정 원숭이...
다 기억하지 못할 정도로 많습니다.

Penguin-'Fota wildlife park'

원숭이 못지않게 새 종류도 다양한데,
그 중 가장 눈에 띈 건 펭귄입니다.
아주 추운 데서만 사는 줄 알았는데,
얼음이 없어도 잘 지내더군요.
돌 위에 배를 깔고 누워있기도 하고, 일어나서 뒤뚱뒤뚱 걷기도 합니다.
다른 펭귄과 별다를 것이 없어요.

Cheetah-'Fota wildlife park'

치타는 슬픈 눈을 하고 우리 안에 갇혀 있습니다.
‘내가 이 좁은 데서 뭘 하는 건지. 휴.’
한숨 소리가 들리는 듯하군요.
먼 곳을 응시하며 깊은 사유에 잠긴 그에겐 이곳이 낯설기만 합니다.

Giraffe-'Fota wildlife park'

동물원 하면 생각나는 동물은 또 뭐가 있을까요?
네. 기린입니다.
아무 말 없이 조용조용 걸어 다니더라고요.
그러고 보니 지금껏 기린이 우는 소리를 한 번도 못 들어봤습니다.
소는 음메 하고, 양은 메~ 하는데.
기린은 목이 너무 길어서 목소리가 입까지 못 올라오는 걸까요?

포타 동물원(Fota wildlife park) 웹사이트



by


Tags : , , , , ,

  • 재미있게 읽으셨나요?
    광고를 클릭해주시면,
    블로그 운영에 큰 도움이 됩니다!

파도가 철썩 하고, 절벽을 때린다. 클리프 모허.

관광 버스~ 유후~-'Cliffs of Moher'

전에 한 번 이용했던 여행사 패디웨곤(Paddywagon)을 통해 클리프 모허를 다녀왔습니다.
아일랜드에서 손에 꼽는 명소로 알려진 곳이에요.
꽤 볼 만한 곳이지만,
가슴을 탁 트이게 할 정도의 감동은 받지 못했습니다.

절벽~-'Cliffs of Moher'

날씨가 아주 화창했던 걸 고려하면, 그냥 그런 곳이죠.
아일랜드는 햇빛만 비추면 어디든 멋지니까요.^^;
이름을 날릴 대로 날린 이곳은 관광지답게 길도 참 깔끔하게 잘 나 있습니다.
한 바퀴 휙~ 돌아보는데 한 시간이면 충분했어요.
이런 데는 돗자리 들고와서 갈매기를 벗 삼아 바다와 술잔을 기울이러 와야 되는데 말이죠.
눈인사나 한번 하고 지나간다면 대화를 나누기 어렵잖아요?
그럼에도 사람들은 커다란 버스를 타고 이곳을 구경하러 옵니다.

관광 버스~ 유후~-'Cliffs of Moher'

저도 관광객답게 인증사진을 찍었어요.
다음에 와서 돗자리 깔기엔 이 자리가 딱 좋겠다는 생각입니다.
경치가 꽤 멋지죠?
아일랜드는 섬나라니 어느 쪽으로 가든지 바다 구경하기는 쉽습니다.
그런데 가까운 바다 두고 굳이 여기까지 구경을 오는 이유가 뭘까 생각해봤어요.
그러고 보면 제가 한국에서 살던 곳은 서해가 코 앞인데,
동해나 남해로 떠날 때가 잦았던 기억이네요.
아무래도 클리프 모허가 사람을 끌어들이는 마력이 있나 봅니다.
경치 말고도, 이곳의 이름이 날리는 이유가 또 하나 있어요.
아일랜드의 자살 명소로 유명합니다.
“클리프 모허 다녀왔음!”이라고 말했을 때,
“죽지 않았네?”라고 되묻는 사람이 있을 정도예요.
죽으려고 작정하고 간 게 아니라도,
저 아름다운 바다를 보고 있노라면 뛰어들고 싶은 충동이 들만도 합니다.
바다잖아요?
그러니 바다에 익숙하지 않다면,
우선 해수욕장에 가서 소금물부터 실컷 마시고 가는 게 목숨을 살리는 길입니다.

고인돌~-'Cliffs of Moher'

클리프 모허를 들르고 돌아오는 길에 관광버스가 고인돌 앞에 멈추었습니다.
고인돌이 귀엽더라고요.
집 근처 강화도에서 워낙 커다란 돌땡이를 가져다 놓은 걸 봐서 그런가 봐요.
제가 보기엔 고인돌 주변에 깔린 돌이 더 멋졌습니다.
바위 사이사이로 풀이 자라나는 모습이 인상 깊었어요.
클리프 모허.
코크에서 부담 없이 당일 여행으로 다녀올 만한 코스입니다.



by


Tags : , , , ,

  • 재미있게 읽으셨나요?
    광고를 클릭해주시면,
    블로그 운영에 큰 도움이 됩니다!

아틀란티스 인이 남긴 연금술의 비밀. 에메랄드 태블릿.

‘아틀란티스 사람이 쓴 책이라니!’
뭔가 엄청난 게 들어있을 법합니다.
돌을 황금으로 만드는 연금술이 아니라,
흙처럼 살던 사람이 빛의 삶으로 거듭나게 하는 연금술!
친구가 꼭 읽어보라며 몇 번이고 추천을 했던 책이죠.
‘과연 이 책장을 넘기면 어떤 내용이 살아 숨 쉴까?’
딱히 신선한 게 없군요.
에메랄드 태블릿이 기독교 문화권의 사람이 쓴 판타지이던가,
혹은 그 반대로 성경이 이 책의 영향을 많이 받은듯 보입니다.
어쨌거나 둘은 뿌리가 같아요.
불의 인간이라던가,
일주일에 한 번은 쉬라던가,
삼위일체를 강조하는 점이 그렇습니다.
성경처럼 선과 악, 즉 빛과 어둠을 대립 구도로 놓고 이야기해요.
게다가 Y.H.V.H까지 등장하는걸요.
성경과 좀 다른 내용이라면 만트라를 이용한 수행법 정도일까요?
글을 읽는 내내 느낀 점은 문체에 힘이 없다는 겁니다.
성경만큼이나 믿음과 복종에 관한 이야기가 많이 나오는 이유가 바로 그거에요.
확신이 없는 가설을 글로 옮긴다면 자신감이 떨어지죠.
자신조차 모르는 세계를 남에게 믿게 하려다 보니, 믿음과 복종을 강요하게 된 겁니다.
저는 번역서만 읽었으니, 몇번의 번역을 거치는 과정에서 번역자의 생각이 첨부되어 그럴지도 모릅니다.
아무튼 확실한 것엔 믿음이 필요 없어요.
‘해가 뜨면 밝고, 그것이 지면 어둡습니다.’
이 말엔 굳이 믿으라는 말을 덧붙일 필요가 없죠.
보편적인 진리니까요.
에메랄드 태블릿에서 흥미롭게 읽은 부분이 있습니다.
천부경의 ‘하나에서 시작하지만 그 시작이란 건 없다. (일시무시일(一始無始一))’
불경의 ‘무상·고·무아 (삼법인(三法印))’
를 떠올리게 하는 생과 멸의 이론입니다.
두 경전과는 다른 각도에서 바라본 점이 흥미롭더군요.
0과 1이 변하는 속도,
즉 꺼짐과 켜짐의 속도가 어느 한계점에 다다르면, 변화의 속도가 아주 빠르므로 생도 없고 멸도 없다는 이론입니다.
그러니 생과 멸을 초월하기 위해 노력을 게을리하지 말라고 하네요.
설령 그것이 가능하다 해도 천성이 게으른 저와는 상성이 맞지 않는군요.^^;
에메랄드 태블릿.
깨달음의 책이라 말하기는 무리고, 그렇다고 판타지로 보자면 지루한 책이었습니다.



by


Tags : , , , ,

  • 재미있게 읽으셨나요?
    광고를 클릭해주시면,
    블로그 운영에 큰 도움이 됩니다!

낙태. 여대생 가비타는 왜 사 개월, 삼 주 그리고 이틀 만에 임신 중절을 해야 했나?

4 Months, 3 Weeks  and 2 Days

어느 날 생각지도 못하게 임신을 했다면?
심경이 복잡하겠지만, 단순한 선택지가 눈앞에 놓입니다.
‘낳을 것인가, 지울 것인가?’
어떤 선택을 해도 사회가 바라보는 시선은 따갑기만 합니다.
낳기로 하면, 결혼도 하기 전에 애부터 만들었다고 삐딱하니 보고,
지운다고 하면, 생명의 소중함을 모르는 사람이 되고 맙니다.
심지어 우리나라에선 성폭행으로 말미암은 임신, 산모의 삶, 신체적 건강, 기타 중대한 문제가 없는 한 모든 낙태 수술이 불법이기까지 합니다.
그럼에도 낙태를 하는 사람은 어째서 그런 결정을 내려야만 했을까요?
한국에서 미혼 여성의 인공임신중절률이 다시 증가하고 있다고 합니다.
산부인과 의사들을 대상으로 한 조사에선 ‘혼전 성교 및 미혼임신의 증가’와 ‘경제적 상황의 악화’가 낙태의 가장 큰 증가요인이라고 대답을 했다고 하는군요.

미혼 여성이 아이를 낳더라도,
먹고 사는 데 문제가 없다면 낙태를 선택하는 일이 줄어들 겁니다.
하지만 당장 다음 달 월세를 못 내면 거리에 나앉을 판에 아이까지 책임지긴 부담스럽겠죠.
요즘 최저임금 시급으론 따듯한 밥 한 끼 사 먹기도 어려워요.
최저임금을 받고 산다면, 과일 하나 사 먹으려고 해도 몇 번을 망설이게 됩니다.
제대로 먹지도 못하며 고된 일에 시달리다가 덜컥 애가 생기면 걱정부터 생기기 마련이죠.
그러니 미혼 여성의 낙태를 막기 위해선 최저임금의 인상과 기본 생존권 보장이 필요합니다.
법으로 위협해서 낙태를 못 하도록 할 것이 아니라,
누구든지 먹고는 살도록 정책을 편다면 경제적 상황의 악화로 말미암은 낙태율은 자연스레 줄어들 것입니다.
‘혼전 성교 및 미혼임신의 증가’
관계를 자체를 갖지 않으면 미혼 여성이 임신 중절할 일도 없습니다.
말로야 쉽죠.
하지만 어찌 사람 사는 세상이 그렇습니까.
피가 뜨거운 남녀가 만난다면, 언제 일이 벌어져도 이상할 것이 없습니다.
그렇다고 혈기 왕성한 남녀 보고 아주 만나지 말라고 할 순 없으니, 다른 대안이 없을까요?
어려서부터 성에 대한 체계적인 교육이 필요하다고 봅니다.
요즘은 어떤지 몰라도 제가 어릴 땐 성 교육이 참 얼렁뚱땅이었어요.
교과서 펴놓고 하는 난소가 어떻고 정자가 어떻다는 얘기가 전혀 피부에 와 닿지 않았습니다.
낙태요?
말로만 들었지 그 과정이 어떤지 상상하기 어려웠습니다.
그리고 가까운 사람이 낙태하지 않는다면, 그때의 심정을 어떻게 알겠어요.
사 개월, 삼 주 그리고 이틀은 낙태를 간접적으로나마 겪을 기회를 줍니다.
충격적이었어요.
비록 미성년자 관람 불가 영화이지만,
학생들의 성교육용으로 좋겠단 생각이 듭니다.
이 영화를 본다면,
관계를 갖기 전에 이런 일이 벌어질지도 모른다고 한 번쯤은 떠올릴 테니까요.



by


Tags : , , , , , ,

  • 재미있게 읽으셨나요?
    광고를 클릭해주시면,
    블로그 운영에 큰 도움이 됩니다!