diff --git a/composer.json b/composer.json
index 345bbdefad5cc6595dc140e8c5313abaa22474f0..6a79cb8b9cb4beafebefa156376aceb5fd0e654b 100644
--- a/composer.json
+++ b/composer.json
@@ -1,5 +1,6 @@
 {
   "name": "wpdesk/wp-forms",
+  "description": "WP Forms",
   "authors": [
     {
       "name": "Marcin",
@@ -8,6 +9,10 @@
     {
       "name": "Krzysiek",
       "email": "krzysiek@wpdesk.pl"
+    },
+    {
+      "name": "Piotr Potrebka",
+      "email": "piotr.potrebka@wpdesk.pl"
     }
   ],
   "require": {
@@ -31,6 +36,13 @@
   },
   "autoload-dev": {
   },
+  "extra": {
+    "text-domain": "wp-forms",
+    "translations-folder": "lang",
+    "po-files": {
+      "pl_PL": "pl_PL.po"
+    }
+  },
   "scripts": {
     "phpunit-unit": "phpunit --configuration phpunit-unit.xml --coverage-text --colors=never",
     "phpunit-unit-fast": "phpunit --configuration phpunit-unit.xml --no-coverage",
diff --git a/lang/pl_PL.mo b/lang/pl_PL.mo
new file mode 100644
index 0000000000000000000000000000000000000000..f621cb5cbf4b151eecddd0e12ca29f4eee4f51c7
Binary files /dev/null and b/lang/pl_PL.mo differ
diff --git a/lang/pl_PL.po b/lang/pl_PL.po
new file mode 100644
index 0000000000000000000000000000000000000000..9fcc8e92b2a6dd2987c89caafb57e27db9785064
--- /dev/null
+++ b/lang/pl_PL.po
@@ -0,0 +1,44 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: WP Forms\n"
+"POT-Creation-Date: 2021-05-24 10:07+0200\n"
+"PO-Revision-Date: 2021-05-24 10:07+0200\n"
+"Last-Translator: Piotr Po <potreb@gmail.com>\n"
+"Language-Team: Piotr Potrebka <piotr.potrebka@gmail.com>\n"
+"Language: pl_PL\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 2.3\n"
+"X-Poedit-Basepath: ..\n"
+"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
+"|| n%100>=20) ? 1 : 2);\n"
+"X-Poedit-SourceCharset: UTF-8\n"
+"X-Poedit-KeywordsList: __;_e;_n:1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;esc_attr__;"
+"esc_attr_e;esc_attr_x:1,2c;esc_html__;esc_html_e;esc_html_x:1,2c;_n_noop:1,2;"
+"_nx_noop:3c,1,2;__ngettext_noop:1,2\n"
+"X-Poedit-SearchPath-0: .\n"
+"X-Poedit-SearchPath-1: src\n"
+"X-Poedit-SearchPathExcluded-0: *.js\n"
+"X-Poedit-SearchPathExcluded-1: vendor\n"
+"X-Poedit-SearchPathExcluded-2: vendor_prefixed\n"
+
+#: templates/input-image.php:24
+msgid "Set image"
+msgstr "Wstaw obraz"
+
+#: templates/input-image.php:29
+msgid "Remove image"
+msgstr "Usuń obraz"
+
+#: templates/input-image.php:50
+msgid "Select or Upload Media"
+msgstr "Wybierz lub prześlij media"
+
+#: templates/input-image.php:52
+msgid "Use this media"
+msgstr "Wybierz"
+
+#: templates/product-select.php:13
+msgid "Search for a product&hellip;"
+msgstr "Szukaj produktu&hellip;"
diff --git a/src/Field/ImageInputField.php b/src/Field/ImageInputField.php
new file mode 100644
index 0000000000000000000000000000000000000000..dd4226c14e7e0a051c4ca077c3d870fde3643e91
--- /dev/null
+++ b/src/Field/ImageInputField.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace WPDesk\Forms\Field;
+
+class ImageInputField extends \WPDesk\Forms\Field\BasicField {
+
+	public function __construct() {
+		parent::__construct();
+		$this->set_default_value( '' );
+		$this->set_attribute( 'type', 'text' );
+	}
+
+	/**
+	 * @return string
+	 */
+	public function get_template_name() {
+		return 'input-image';
+	}
+}
diff --git a/src/Field/MultipleInputTextField.php b/src/Field/MultipleInputTextField.php
new file mode 100644
index 0000000000000000000000000000000000000000..fab83989cda40645ab355f631dc7ec1665c61185
--- /dev/null
+++ b/src/Field/MultipleInputTextField.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace WPDesk\Forms\Field;
+
+class MultipleInputTextField extends InputTextField {
+
+	/**
+	 * @return string
+	 */
+	public function get_template_name() {
+		return 'input-text-multiple';
+	}
+}
diff --git a/templates/input-image.php b/templates/input-image.php
new file mode 100644
index 0000000000000000000000000000000000000000..8b805c6d977cccdff1d187eaf0c802c83041cb3e
--- /dev/null
+++ b/templates/input-image.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ * @var \WPDesk\Forms\Field $field
+ * @var string              $name_prefix
+ * @var string              $value
+ */
+?>
+<?php
+$media_container_id = 'media_' . sanitize_key( $field->get_id() );
+?>
+<div class="media-input-wrapper" id="<?php echo $media_container_id; ?>">
+    <input type="hidden" class="image-field-value" value="<?php echo \esc_html( $value ); ?>"
+           name="<?php echo \esc_attr( $name_prefix ) . '[' . \esc_attr( $field->get_name() ) . ']'; ?>"
+           id="<?php echo \esc_attr( $field->get_id() ); ?>"/>
+    <div class="custom-img-container">
+		<?php if ( $value ) : ?>
+            <img src="<?php echo $value ?>" alt="" width="100"/>
+		<?php endif; ?>
+    </div>
+    <p class="hide-if-no-js">
+        <a class="upload-custom-img <?php if ( $value ) {
+			echo 'hidden';
+		} ?>" href="<?php echo $value ?>">
+			<?php _e( 'Set image', 'wp-forms' ) ?>
+        </a>
+        <a class="delete-custom-img <?php if ( ! $value ) {
+			echo 'hidden';
+		} ?>" href="#">
+			<?php _e( 'Remove image', 'wp-forms' ) ?>
+        </a>
+    </p>
+</div>
+<script>
+	jQuery( function ( $ ) {
+		var frame,
+			metaBox = $( '#<?php echo $media_container_id; ?>' ),
+			addImgLink = metaBox.find( '.upload-custom-img' ),
+			delImgLink = metaBox.find( '.delete-custom-img' ),
+			imgContainer = metaBox.find( '.custom-img-container' ),
+			imgIdInput = metaBox.find( '.image-field-value' );
+
+		addImgLink.on( 'click', function ( event ) {
+			event.preventDefault();
+			if ( frame ) {
+				frame.open();
+				return;
+			}
+
+			frame = wp.media( {
+				title: <?php _e( 'Select or Upload Media', 'wp-forms' ); ?>,
+				button: {
+					text: <?php _e( 'Use this media', 'wp-forms' ); ?>
+				},
+				library: {
+					type: ['image']
+				},
+				multiple: false
+			} );
+
+			frame.on( 'select', function () {
+				var attachment = frame.state().get( 'selection' ).first().toJSON();
+				imgContainer.append( '<img src="' + attachment.url + '" alt="" width="100" />' );
+				imgIdInput.val( attachment.url );
+				addImgLink.addClass( 'hidden' );
+				delImgLink.removeClass( 'hidden' );
+			} );
+			frame.open();
+		} );
+
+		delImgLink.on( 'click', function () {
+			imgContainer.html( '' );
+			addImgLink.removeClass( 'hidden' );
+			delImgLink.addClass( 'hidden' );
+			imgIdInput.val( '' );
+			return false;
+		} );
+
+	} );
+</script>
diff --git a/templates/input-text-multiple.php b/templates/input-text-multiple.php
new file mode 100644
index 0000000000000000000000000000000000000000..7d3fff829b5f52988afb67e097dac6aaed342495
--- /dev/null
+++ b/templates/input-text-multiple.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ * @var \WPDesk\Forms\Field $field
+ * @var \WPDesk\View\Renderer\Renderer $renderer
+ * @var string $name_prefix
+ * @var string $value
+ *
+ * @var string $template_name Real field template.
+ *
+ */
+?>
+<?php
+if( empty( $value ) || is_string( $value ) ) {
+	$input_values[] = '';
+} else {
+	$input_values = $value;
+}
+?>
+<div class="clone-element-container">
+<?php foreach( $input_values as $text_value ): ?>
+<?php if (!\in_array($field->get_type(), ['number', 'text', 'hidden'])): ?>
+	<input type="hidden" name="<?php echo $name_prefix.'['.$field->get_name().']'; ?>" value="no"/>
+<?php endif; ?>
+
+<?php if ($field->get_type() === 'checkbox' && $field->has_sublabel()): ?><label><?php endif; ?>
+	<div class="clone-wrapper">
+	<input
+		type="<?php echo \esc_attr($field->get_type()); ?>"
+		name="<?php echo \esc_attr($name_prefix).'['.\esc_attr($field->get_name()).'][]'; ?>"
+		id="<?php echo \esc_attr($field->get_id()); ?>"
+
+		<?php if ($field->has_classes()): ?>
+			class="<?php echo \esc_attr($field->get_classes()); ?>"
+		<?php endif; ?>
+
+		<?php if ($field->get_type() === 'text' && $field->has_placeholder()):?>
+			placeholder="<?php echo \esc_html($field->get_placeholder());?>"
+		<?php endif; ?>
+
+		<?php foreach ($field->get_attributes() as $key => $atr_val):
+			echo $key.'="'.\esc_attr($atr_val).'"'; ?>
+		<?php endforeach; ?>
+
+		<?php if ($field->is_required()): ?>required="required"<?php endif; ?>
+		<?php if ($field->is_disabled()): ?>disabled="disabled"<?php endif; ?>
+		<?php if ($field->is_readonly()): ?>readonly="readonly"<?php endif; ?>
+		<?php if (\in_array($field->get_type(), ['number', 'text', 'hidden'])): ?>
+			value="<?php echo \esc_html($text_value); ?>"
+		<?php else: ?>
+			value="yes"
+			<?php if ($value === 'yes'): ?>
+				checked="checked"
+			<?php endif; ?>
+		<?php endif; ?>
+	/>
+		<span class="add-field"><span class="dashicons dashicons-plus-alt"></span></span>
+		<span class="remove-field hidden"><span class="dashicons dashicons-remove"></span></span>
+	</div>
+
+	<?php if ($field->get_type() === 'checkbox' && $field->has_sublabel()): ?>
+	<?php echo \esc_html($field->get_sublabel()); ?></label>
+<?php endif; ?>
+<?php endforeach; ?>
+</div>
+<style>
+    .clone-element-container .clone-wrapper .add-field {
+        display: none;
+    }
+    .clone-element-container .clone-wrapper:first-child .add-field {
+        display: inline-block;
+    }
+
+    .clone-element-container .clone-wrapper .remove-field {
+        display: inline-block;
+    }
+    .clone-element-container .clone-wrapper:first-child .remove-field {
+        display: none;
+    }
+</style>
+<script>
+	jQuery( function ( $ ) {
+		var add_field = jQuery( '.add-field' );
+		if ( add_field.length ) {
+			add_field.click( function ( e ) {
+				let html = jQuery( this ).closest( '.clone-wrapper' ).clone();
+				html.find( 'input' ).val( '' );
+				jQuery( this ).closest( '.clone-wrapper' ).after( html );
+			} )
+
+			jQuery( '.clone-element-container' ).on( "click", ".remove-field", function ( e ) {
+				let is_disabled = jQuery( this ).hasClass( 'field-disabled' );
+				if ( !is_disabled ) {
+					jQuery( this ).closest( '.clone-wrapper' ).remove();
+				}
+			} )
+
+			jQuery( '.form-table' ).find( 'input,select' ).each( function ( i, v ) {
+				let disabled = jQuery( this ).attr( 'data-disabled' );
+				if ( disabled === 'yes' ) {
+					jQuery( this ).attr( 'disabled', 'disabled' )
+					jQuery( this ).parent().addClass( 'field-disabled' );
+				}
+			} );
+		}
+	} );
+</script>